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

Introduction

Welcome to the official documentation for Dioxamine.

Dioxamine is a fast, modern Android application designed for Android enthusiasts, developers, and technicians. It allows you to control secondary Android devices, send ADB commands, mirror and stream displays or cameras with Scrcpy, flash Fastboot firmware, manage files and apps, and run custom Web plugins directly from your phone.

What You Can Do with Dioxamine

  1. Connect Devices Anywhere: Connect target devices via USB OTG cable adapters, Wireless ADB auto-discovery, Android 11+ QR code scanning, pairing code PINs, or direct TCP/IP.
  2. Built-in ADB Tools:
    • Inspect full hardware specifications, CPU telemetry, battery status, and uptime.
    • Browse, upload, download, rename, and delete files on target storage.
    • Install APKs, split APK bundles (.apks, .xapk), pull installed apps, and enable or disable system packages.
    • Control Android TV and phones using a D-pad remote control or a full trackpad with virtual PC hardware keyboard.
    • Capture screenshots and execute interactive ADB shell commands.
    • Sideload recovery updates, wipe userdata in Rescue mode, and reboot into System, Recovery, Bootloader, or Fastbootd.
  3. Scrcpy Screen Mirroring and Camera Streaming:
    • Low-latency screen mirroring with touch control and audio forwarding.
    • Stream high-speed target camera video with lens selection, frame rate controls, and remote flashlight toggle.
  4. Fastboot Tools:
    • Flash partition images (boot, recovery, system, vendor_boot, init_boot) with live transfer progress.
    • Live boot custom kernels or recovery images without overwriting partitions.
    • Lock and unlock bootloader states.
  5. Web Plugin System:
    • Build and install modular HTML5/JavaScript plugins with full bridge access to ADB, shell, and file transfers.

Documentation Overview

This manual is organized into two main parts:

  • App User Guide: Complete instructions on connecting devices, using each built-in tool, tuning Scrcpy mirroring, flashing in Fastboot mode, and configuring app settings.
  • Plugin Development Guide: Complete technical specification and JavaScript bridge reference for creating custom Dioxamine plugins.

Getting Started

This guide introduces Dioxamine, its navigation layout, and how to start managing secondary Android devices.

App Layout and Navigation

Dioxamine is organized into four main tabs along the bottom navigation bar:

  1. ADB: The central hub for ADB device management. Contains device connection controls, built-in device tools (File Manager, Package Manager, Remote Control, Touchpad, Screenshots, Reboot Menu, Sideload), an interactive ADB terminal, and custom Web plugins.
  2. Scrcpy: Real-time screen mirroring, remote touch interaction, audio forwarding, and target camera video streaming.
  3. Fastboot: Bootloader flashing utilities, kernel booting, lock state management, variable inspection, and raw Fastboot command execution.
  4. Settings: ADB RSA key management (generation, export, import), Material 3 Monet theming, language configuration, diagnostic log export, and plugin security permissions.

Requirements

To use Dioxamine effectively, ensure your setup meets the following requirements:

Host Phone (Running Dioxamine)

  • Android 7.0 (Nougat, API 24) or newer.
  • USB OTG support if connecting via cable.
  • Dynamic Material 3 colors (Monet) require Android 12 or newer.

Target Device (Device Being Controlled)

  • Developer Options enabled.
  • USB Debugging enabled (for USB OTG or TCP connections).
  • Wireless Debugging enabled (for Android 11+ Wi-Fi connections).
  • For Scrcpy audio forwarding: target device must run Android 11 (API 30) or newer.
  • For Scrcpy camera streaming: target device must run Android 12 (API 31) or newer.
  • For Scrcpy audio duplication without muting the target: target device must run Android 13 (API 33) or newer.

Enabling Developer Options on Target Device

Before connecting any target device:

  1. Open Settings on the target device.
  2. Navigate to About Phone (or About Device).
  3. Tap Build Number repeatedly (usually 7 times) until a message appears saying “You are now a developer!”.
  4. Go back to Settings > System > Developer Options (location varies slightly by manufacturer).
  5. Toggle USB Debugging to ON.
  6. If connecting wirelessly on Android 11+, also toggle Wireless Debugging to ON.

Connecting Devices

Dioxamine provides multiple connection methods to interface with secondary Android devices over physical cables or local Wi-Fi networks.

Connection Methods Overview

MethodBest Used ForRequirements
USB OTG CableMaximum reliability, initial wireless setup, Fastboot flashingUSB OTG adapter/cable, USB Debugging enabled
Wireless Auto-DiscoveryQuick Wi-Fi connection without typing IP addressesBoth devices on the same Wi-Fi network, mDNS enabled
QR Code PairingFastest wireless setup on Android 11+Android 11+ target, camera permission on host
Pairing Code / PINAndroid 11+ pairing when QR scanning is not availableAndroid 11+ target, 6-digit PIN and pairing port
Direct TCP/IPLegacy wireless connection or static IP environmentsPort 5555 enabled on target, shared network

1. USB OTG Cable Connection

Connecting over USB OTG provides the fastest and most stable link between devices.

Step-by-Step Instructions:

  1. Plug a USB OTG adapter into your host phone (the phone running Dioxamine).
  2. Connect a USB cable from the adapter to the target device.
  3. On your host phone, Android will display a popup: “Allow Dioxamine to access this USB device?”. Tap OK.
  4. On the target phone screen, look for the prompt: “Allow USB debugging?”.
  5. Check the box “Always allow from this computer” and tap Allow.
  6. Dioxamine will automatically detect the device and display its model name in the top device chip bar.

Note

If the target device does not show the debugging prompt, check whether the USB cable supports data transfer (some cables are charge-only). Also verify that USB Debugging is toggled on in Developer Options.


2. Wireless ADB Auto-Discovery

If both devices are connected to the same Wi-Fi network or if one device is connected to the other’s portable hotspot, Dioxamine can automatically discover the target device using mDNS.

Step-by-Step Instructions:

  1. On the ADB tab in Dioxamine, tap the Add Device (+) button in the top bar.
  2. The Discovered Devices dialog will appear and begin scanning your local network.
  3. Look for your target device in the list:
    • Devices marked with TLS are already paired and ready to connect. Tap the device to connect immediately.
    • Devices marked with Pairing require pairing first. Tap the device to open the pairing code input screen.
    • Devices marked with TCP are listening on standard ADB ports. Tap to connect directly.

3. Wireless ADB QR Code Pairing (Android 11+)

Android 11 and newer support native Wireless Debugging with QR code pairing.

Step-by-Step Instructions:

  1. Connect both devices to the same Wi-Fi network or mobile hotspot.
  2. In Dioxamine on your host phone, tap the QR Pairing icon in the top connector bar. Dioxamine starts a local pairing server and presents a styled pairing QR code on screen.
  3. On the target device, navigate to Settings > Developer Options > Wireless Debugging.
  4. Tap Pair device with QR code to open the target device’s built-in QR scanner.
  5. Point the target device’s camera at the QR code displayed on your host phone screen.
  6. Once scanned, the target authenticates over TLS, and Dioxamine automatically connects to the discovered wireless debugging port.

4. Manual Pairing Code (Android 11+)

If camera scanning is not possible, you can pair manually using the 6-digit Wi-Fi pairing code.

Step-by-Step Instructions:

  1. On the target device, go to Settings > Developer Options > Wireless Debugging.
  2. Tap Pair device with pairing code.
  3. The target screen will show:
    • Wi-Fi pairing code (a 6-digit number, for example: 123456).
    • IP address & Port (for example: 192.168.1.50:37123).
  4. In Dioxamine, tap Add Device (+) > Manual Entry > Wireless Debugging (TLS) > Pair with Code.
  5. Enter the IP address, the Pairing Port shown in the popup (e.g., 37123), and the 6-digit pairing code.
  6. Tap Pair.
  7. Once paired successfully, Dioxamine will transition to the Connect screen. Enter the main connection port shown on the target’s main Wireless Debugging page and tap Connect.

5. Direct TCP/IP Connection (Port 5555)

Used for devices running Android 10 or older, Android TV boxes with fixed IP addresses, or devices configured with ADB over TCP.

Connecting Directly:

  1. Tap Add Device (+) > Manual Entry > Plain TCP (IP:Port).
  2. Enter the target IP address and port (default is 5555).
  3. Tap Connect.

Switching a USB Device to TCP/IP:

If you currently have a device plugged in via USB OTG and want to disconnect the cable and continue wirelessly:

  1. Ensure both devices are connected to the same Wi-Fi.
  2. In the top device connector card, tap the three-dots menu next to the USB device.
  3. Tap Switch to TCP/IP.
  4. Set the port (default 5555) and confirm.
  5. You can now unplug the USB cable and connect to the target’s IP address over Wi-Fi.

OEM-Specific Setup and Troubleshooting

Certain Android manufacturers include custom security layers, battery optimizers, or modified permission frameworks that require specific adjustments for ADB, Touch Control, and Screen Mirroring to function properly.


Xiaomi / Redmi / POCO (HyperOS and MIUI)

Xiaomi devices impose strict limitations on remote ADB input and background automation by default.

Required Settings:

  1. Open Settings > Additional Settings > Developer Options.
  2. Enable USB debugging.
  3. Enable Install via USB (allows Dioxamine to install APKs and push helper tools).
  4. Enable USB debugging (Security settings):
    • This setting allows Dioxamine to send touch events, simulate keypresses, and control the screen via Scrcpy or Touchpad.
    • Xiaomi requires a working SIM card and a signed-in Mi Account to enable this toggle. Follow the on-screen countdown prompts.
  5. If using Wireless Debugging, also enable Wireless Debugging.

Warning

If USB debugging (Security settings) is disabled, screen mirroring will work, but you will not be able to tap, swipe, or send keystrokes to the target device.


Samsung (One UI)

Samsung devices generally work smoothly with ADB, but consider the following:

  1. Go to Settings > Developer Options.
  2. Enable USB Debugging.
  3. If connecting via Wireless Debugging on One UI 3.0+ (Android 11+), ensure Wireless Debugging is toggled on.
  4. Disable Auto Blocker (One UI 6.0+ / Android 14+):
    • Navigate to Settings > Security and Privacy > Auto Blocker.
    • If Auto Blocker is enabled, it blocks all USB command execution and package installations via ADB. Turn Auto Blocker OFF or customize its restrictions to allow ADB commands.
  5. In Developer Options, turn off Verify apps over USB if package installations hang or prompt repeatedly.

OnePlus / OPPO / Realme (ColorOS / OxygenOS / Realme UI)

  1. Open Settings > Additional Settings (or System Settings) > Developer Options.
  2. Toggle on USB Debugging.
  3. Enable Disable Permission Monitoring:
    • This prevents ColorOS from popping up a confirmation prompt on the target device every time an automated touch event or shell command is executed.
  4. If installing applications fails, ensure Install via USB or Verify ADB installs is properly configured.

Huawei / Honor (EMUI / MagicOS)

  1. Go to Settings > System & updates > Developer options.
  2. Enable USB debugging.
  3. Enable “Allow ADB debugging in charge only mode”:
    • Huawei devices often switch USB connections to Charge Only mode when connected via OTG. Enabling this setting ensures the ADB daemon remains active.

Android TV / Google TV Boxes

  1. Open TV Settings > Device Preferences > About.
  2. Tap Android TV OS Build 7 times to enable Developer Options.
  3. Return to Device Preferences > Developer Options.
  4. Enable USB Debugging and Network Debugging (if available).
  5. When connecting Dioxamine, keep the TV screen on so you can click “Always allow from this computer” using your TV remote control.

ADB Tools Overview

When a device is connected and active in the ADB tab, Dioxamine offers three sub-tabs at the top:

  1. Built-in Actions: A curated suite of management tiles for hardware telemetry, remote control, trackpad input, file management, app installation, screenshot capture, and rebooting.
  2. ADB Shell: An interactive terminal emulator for direct command-line execution.
  3. Plugins: Web-based modular extensions installed into Dioxamine.

Built-in Actions Suite

The Built-in Actions sub-tab provides quick access to 10 essential tool tiles:

  • Device Information: Quick inspect for hardware model, Android version, battery percentage, serial number, processor details, screen resolution, and installed package counts.
  • Process Manager: Live CPU and RAM utilization monitor, process inspector, search filter, Force Stop, and PID termination powered by DioxAgent.
  • Miscellaneous: Quick tweaks for display density (DPI), resolution, screen orientation, stay awake, demo mode, touch/pointer visualization, window animations, battery emulation, and deep link launching.
  • Remote Control: A directional D-pad remote with power, volume, media playback, TV input switching, and text injection controls tailored for phones and Android TVs.
  • Touchpad & PC Keyboard: Transform your phone into a full laptop trackpad and full-featured hardware keyboard with modifier keys, function keys, and live soft typing.
  • File Manager: Explore internal storage (/sdcard) and root directories, push multiple files from your phone, pull files back, rename, and manage folders.
  • Package Manager: Inspect installed user and system apps, install new APKs/split APKs (.apks, .xapk), pull installed apps with split reconstruction, disable bloatware, and force-stop apps.
  • Screenshot: Take instant PNG screenshots of the target device screen and save them to local storage.
  • Reboot Menu: Quickly restart into Android System, Recovery, Bootloader, Fastbootd, or shut down.
  • Sideload & Rescue: Automatically triggered when a device is connected in Recovery Sideload mode or Rescue mode to flash OTA update zips or wipe userdata.

Device Information

The Device Information tool provides an instant diagnostic summary of the target device’s hardware, software version, and real-time operating metrics.

Accessing Device Information

  1. Open the ADB tab in Dioxamine.
  2. Select Built-in Actions sub-tab.
  3. Tap on the Device Information tile.

Displayed Metrics

When opened, Dioxamine queries the target device sequentially and displays the following information cards:

CardDescriptionCommand Executed
Device ModelManufacturer marketing name and hardware model numbergetprop ro.product.model
Android VersionOS release version (for example: Android 13, Android 14)getprop ro.build.version.release
Battery InfoReal-time battery charge level, status, temperature, and healthdumpsys battery
Serial NumberTarget device unique serial identifiergetprop ro.serialno
CPU InfoProcessor architecture, core count, and hardware chipsetcat /proc/cpuinfo
UptimeHow long the device has been powered on since the last rebootcat /proc/uptime
Screen ResolutionCurrent display resolution and physical display dimensionswm size
Installed PackagesTotal count of packages currently installed on the targetpm list packages | wc -l

UI Controls

  • Refresh Button (Top Right): Tap the refresh icon in the top app bar to re-query all metrics sequentially from the device.
  • Copying Text: You can long-press and select text within any output card to copy details to your clipboard.

Process Manager

The Process Manager provides real-time hardware telemetry and comprehensive process inspection for connected Android devices. Powered by the lightweight DioxAgent daemon, it streams live memory, CPU utilization, and running process states with low overhead.


Features & Telemetry

1. Live Memory & CPU Stats Cards

  • System Memory: Displays total RAM, currently used RAM, free RAM, and a real-time progress bar with the overall percentage used.
  • CPU Usage: Displays total system CPU utilization percentage along with total CPU core count (e.g. 12.5% · 8 Cores).
  • Collapsible Cards: Tap the arrow button in the top action bar to expand or collapse the RAM and CPU progress bars to maximize vertical screen space for process browsing.

2. Live Process List & Badges

For each active process on the target device, the Process Manager displays:

  • Application Icon: Extracted directly from installed APK packages.
  • Process Name & Package Name: Full identifier for the process and its parent package.
  • RAM Usage: Formatted memory usage in MB or GB.
  • CPU Percentage: Real-time normalized CPU percentage used by the process.
  • Process Metadata Badges:
    • PID: Linux process ID.
    • UID: Android user/app identifier.
    • Threads: Total thread count spawned by the process.
    • System / App: Categorical classification badge.

Filtering and Sorting

Filters

  • All: Shows all running user applications and system processes.
  • Apps: Filters to third-party and user-installed applications.
  • System: Filters to Android OS daemons and system services.

Sorting Options

  • RAM (High to Low): Sort by highest memory consumption.
  • CPU (High to Low): Sort by highest real-time CPU usage.
  • PID (Low to High): Sort sequentially by process ID.
  • Name (A to Z): Sort alphabetically by process name.
  • Use the search bar at the top to filter the list dynamically by process name, package name, or numerical PID.

Process Actions

Tap the three-dots menu on any process item to perform actions:

  1. Force Stop App (am force-stop):
    • Immediately terminates all foreground activities, background services, alarms, and subprocesses associated with the parent app package.
  2. Kill PID (kill -9 / SIGKILL):
    • Sends a direct SIGKILL signal to terminate the specific process ID immediately without waiting for graceful shutdown.

Miscellaneous Tools

The Miscellaneous suite brings together essential device tweaks, display modifiers, UI inspector controls, developer toggles, and system shortcuts into an easy one-tap interface.


1. App & Process Actions

  • Kill Foreground App:
    • Automatically queries the active window manager on the target device to find the currently focused foreground package and force-stops it instantly.
  • Clear Active App Data (pm clear):
    • Prompts for confirmation and resets all application storage, cache, and database logins for the active foreground app.

2. Display & Orientation

  • Set Screen Orientation:
    • Overrides the display orientation to 0° (Portrait), 90° (Landscape Right), 180° (Inverted Portrait), or 270° (Landscape Left).
  • Toggle Auto-Rotate:
    • Toggles the accelerometer-based display rotation on or off.
  • Screen Density (DPI):
    • Inspects the current display density. Allows selecting from preset values or entering a custom DPI between 72 and 1200. Includes a Reset Default button to restore factory settings (wm density reset).
  • Screen Resolution:
    • Queries active screen dimensions and lets you apply custom Width × Height resolutions or reset to device defaults (wm size reset).
  • Keep Screen Awake (Stay Awake):
    • Forces the target device’s display to remain awake while connected over USB.

3. System UI & Notifications

  • Expand Notifications:
    • Pulls down the notification shade.
  • Expand Quick Settings:
    • Pulls down the full Quick Settings tile panel.
  • Collapse Status Bar:
    • Dismisses any open notification or Quick Settings shades.

4. Developer & UI Tweaks

  • Demo Mode (Clean Status Bar):
    • Puts the target device into Android Demo Mode with 100% battery indicator, a clean 12:00 clock, full Wi-Fi/mobile signal bars, and hidden notification icons. Perfect for clean screenshots and recordings.
  • Toggle Show Touches:
    • Enables or disables the visual white touch circle indicator under finger taps (show_touches).
  • Toggle Pointer Location:
    • Overlays touch coordinates, pressure rulers, and finger path crosshairs on top of the screen (pointer_location).
  • Window Animation Speed:
    • Adjusts window animation scale, transition animation scale, and animator duration scale between 0.0x (instant/disabled), 0.5x, 1.0x (default), 1.5x, and 2.0x.

5. Battery Emulation

  • Simulate Battery State:
    • Set custom simulated battery charge percentages (0% to 100%).
    • Toggle simulated AC/USB charging or discharging states.
    • Includes a Reset Simulation button (dumpsys battery reset) to restore real hardware battery monitoring.

  • Open URL / Deep Link:
    • Launches any HTTP/HTTPS URL, deep link URI, or custom scheme directly in the target device’s default web browser or assigned handler application.

File Manager

Dioxamine includes a full-featured remote File Manager that allows you to browse internal storage, upload files, download files to your local phone, create folders, rename, and delete items on the target device.

Opening the File Manager

  1. Open the ADB tab.
  2. Under Built-in Actions, tap the File Manager tile.
  3. The File Manager will initialize and open the primary storage directory (/sdcard).

  • Breadcrumbs Bar (Top): Below the top app bar, a horizontal breadcrumb path shows your current location (e.g. / > sdcard > Download). Tap any folder name in the breadcrumb path to jump directly to it.
  • Entering Folders: Tap on any folder in the list to open it.
  • Parent Directory: Tap the top item .. to navigate one level up.
  • Back Gesture: Pressing the Android back button returns to the previous parent directory.

File Manager Actions

1. Uploading Files to Target (Push)

  1. Navigate to the target folder where you want to save the files (e.g. /sdcard/Download).
  2. Tap the Add (+) icon in the top right app bar.
  3. Your host phone’s system file picker will open.
  4. Select one or multiple files (APKs, images, documents, zips).
  5. Dioxamine will immediately start uploading the files and display live progress bars for each item.

2. Downloading Files to Host Phone (Pull)

  1. Locate the file you want to download on the target device.
  2. Tap the three-dots menu icon on the right side of the file row.
  3. Select Download.
  4. A system save dialog will open on your host phone. Choose where to save the file and tap Save.
  5. Dioxamine will stream the file directly to your phone storage.

3. Creating a New Folder

  1. Navigate to the directory where the new folder should be created.
  2. Tap the New Folder icon in the top app bar.
  3. Enter the desired folder name.
  4. Tap Create.

4. Renaming a File or Folder

  1. Tap the three-dots menu icon next to the target item.
  2. Select Rename.
  3. Edit the full path or name in the text field.
  4. Tap Rename to apply.

5. Deleting a File or Folder

  1. Tap the three-dots menu icon next to the item.
  2. Select Delete.
  3. Confirm the deletion in the warning dialog.

6. Viewing File Properties

  1. Tap on any file, or select Properties from the three-dots menu.
  2. The dialog displays:
    • Name and Full Path
    • Type (File, Directory, or Symlink target)
    • File Size (formatted in KB/MB/GB and exact bytes)
    • Unix Permissions / Mode (e.g. drwxrwxr-x)

7. Searching Files

  • Tap the Search (Magnifying Glass) icon in the top app bar.
  • Type any keywords to filter files and folders in real time within the active directory.

Package Manager

The Package Manager allows you to inspect all installed applications on the target device, install new APKs or split APK bundles, pull installed apps back to your phone, disable bloatware, force stop processes, and uninstall apps.

Opening the Package Manager

  1. Open the ADB tab.
  2. Under Built-in Actions, tap the Package Manager tile.
  3. Dioxamine will stream all installed application packages along with their app icons, labels, package names, and version badges.

Filtering and Searching Apps

  • Search Bar: Tap the Search (Magnifying Glass) icon in the top app bar to filter apps by app title or package name (e.g. chrome or com.android.settings).
  • Filter Dropdown: Tap the Filter List icon in the top app bar to filter apps by category:
    • All: Shows all packages installed on the device.
    • User: Shows only user-installed applications.
    • System: Shows pre-installed system apps and framework services.
    • Disabled: Shows apps that are currently disabled or frozen.

App Card Information

Each application card in the list displays:

  • App Icon: Decoded high-resolution application icon.
  • App Name: Human-readable label (e.g. “YouTube”).
  • Package Name: Unique identifier (e.g. com.google.android.youtube).
  • Badges:
    • v1.2.3: Version name.
    • System: Marks pre-installed system applications.
    • Disabled: Highlights frozen or disabled apps.
    • Splits (N): Indicates the app uses Android App Bundle split APKs.

Package Manager Actions

Tap the three-dots menu on any app tile to perform actions:

1. Enable / Disable (Freeze) App

  • Toggle the package between Enabled and Disabled states (pm disable-user / pm enable).
  • Useful for freezing manufacturer bloatware without root access. Disabled apps cannot run in the background or consume battery.

2. Force Stop App

  • Instantly terminates all running background and foreground processes of the selected application (am force-stop).

3. Pull App (Extract APK to Local Phone)

  • Tap Pull APK to export the installed application from the target device to your host phone storage.
  • Single APK Apps: Extracted directly as a standalone .apk file.
  • Split APK Bundle Apps: Dioxamine automatically pulls the master APK and all architecture/language/density split APKs, assembling them into a standard .apks bundle archive with a generated toc.json manifest.

4. Uninstall App

  • Opens a confirmation dialog and completely removes the application package from the target device (pm uninstall).

5. App Info

  • Opens a detailed dialog showing package paths, version code, target SDK level, and provides a button to launch the App Details page in the target device’s Settings menu.

Installing New Apps (APK, APKS, XAPK, ZIP)

Dioxamine supports installing standalone APKs as well as modern split-APK formats:

  1. In the top app bar of Package Manager, tap the Add (+) icon.
  2. Select your application files from your host phone. You can pick:
    • Standalone .apk files.
    • Multiple split .apk files at once.
    • Bundled .apks, .xapk, or .zip split archive packages.
  3. Dioxamine will automatically extract any archives, establish an atomic install session (pm install-create), stream the splits to the target, and commit the installation.
  4. A toast notification will confirm when the installation is successful.

Remote Control

The Remote Control tool transforms your host phone into a wireless remote controller with directional buttons, volume/power controls, Android TV-specific features, media buttons, and text injection.

Opening Remote Control

  1. Open the ADB tab.
  2. Under Built-in Actions, tap the Remote Control tile.

Automatic Android TV Detection

When opened, Dioxamine queries the target device for Android TV characteristics (such as Leanback UI features):

  • Android TV Mode: Automatically activates television-specific controls (TV Guide, TV Input, Channel +/-) and media playback panels.
  • Standard Android Mode: Streamlined for secondary phones and tablets.
  • Manual Mode Switcher: Tap the dropdown arrow in the top app bar title to manually switch between Android TV and Standard Android modes.

Remote Control Layout

1. Power and Volume Bar (Top)

  • Power Button (Red): Sends power key event (KEYCODE_POWER) to lock, unlock, or wake the device.
  • Mute Button: Toggles audio mute state (KEYCODE_VOLUME_MUTE).
  • Vol - / Vol + Buttons: Lowers or raises system media volume (KEYCODE_VOLUME_DOWN / KEYCODE_VOLUME_UP).

2. Directional Pad (D-Pad)

  • Up, Down, Left, Right Arrows: Navigates through menus, app grids, list views, and TV interfaces.
  • Center OK Button (Primary): Confirms selections and opens selected apps or items (KEYCODE_DPAD_CENTER).

3. Android Navigation Bar

  • Back Button: Navigates back one screen (KEYCODE_BACK).
  • Home Button: Returns immediately to the home launcher screen (KEYCODE_HOME).
  • Recents Button: Opens the multitasking / recent apps view (KEYCODE_APP_SWITCH).
  • Menu Button: Opens the context options menu (KEYCODE_MENU).

4. Android TV Controls (TV Mode Only)

  • TV Guide: Opens the electronic program guide (KEYCODE_GUIDE).
  • TV Input: Cycles through HDMI and auxiliary inputs (KEYCODE_TV_INPUT).
  • Channel Up / Channel Down: Switches channels up or down (KEYCODE_CHANNEL_UP / KEYCODE_CHANNEL_DOWN).
  • Search: Launches voice/text search on the TV interface (KEYCODE_SEARCH).

5. Media Playback Controls (TV Mode Only)

  • Previous: Skips to previous audio/video track (KEYCODE_MEDIA_PREVIOUS).
  • Rewind: Fast-rewinds media playback (KEYCODE_MEDIA_REWIND).
  • Play / Pause (Center Blue): Toggles media playback (KEYCODE_MEDIA_PLAY_PAUSE).
  • Fast Forward: Fast-forwards media playback (KEYCODE_MEDIA_FAST_FORWARD).
  • Next: Skips to next audio/video track (KEYCODE_MEDIA_NEXT).

6. Text Input Injection Bar

Typing on a TV with a directional remote can be slow. Dioxamine lets you type directly from your phone:

  1. Tap the text field at the bottom of the Remote Control screen.
  2. Type any text, URL, or password using your phone keyboard.
  3. Tap the Send icon (or press Enter on your keyboard).
  4. Dioxamine will instantly inject the text string into the focused input field on the target device.

7. Numeric Keypad Drawer

  • Tap the Dialpad icon inside the text input bar to open a 0-9 numeric pad.
  • Useful for entering PINs, channel numbers, or security codes on Android TVs.

Touchpad and PC Keyboard

The Touchpad & PC Keyboard tool turns your host phone into a full-precision laptop trackpad and a complete PC hardware keyboard. It uses virtual HID device drivers over ADB to send native mouse movements, clicks, multi-finger scroll gestures, keyboard shortcuts, and real-time typing.

Opening Touchpad and Keyboard

  1. Open the ADB tab.
  2. Under Built-in Actions, tap the Touchpad tile.
  3. At the top of the screen, choose between two sub-tabs:
    • TouchPad: Full trackpad interface with discrete buttons and quick soft typing.
    • PC Keyboard: Complete desktop keyboard layout with modifier keys, function keys, navigation keys, and shortcuts.

Tab 1: Touchpad Interface

Trackpad Canvas Gestures:

  • Move Pointer: Slide one finger across the trackpad area to move the mouse cursor on the target device.
  • Left Click: Single tap with one finger.
  • Right Click: Long-press on the trackpad, or tap with two fingers.
  • Scroll (Wheel): Drag up or down with two fingers simultaneously to scroll web pages, lists, and documents.
  • Drag and Drop: Double tap, hold your finger down on the second tap, and slide to drag windows or select text.

Discrete Physical Buttons:

Below the trackpad canvas are 3 physical buttons:

  • Left Button: Tap to left click, or press and hold while moving your finger on the canvas to highlight text and drag items.
  • Middle Button: Sends a middle mouse click (KEYCODE_BUTTON_MIDDLE).
  • Right Button: Tap or hold for context menus.

Sensitivity Tuning:

  • Tap the Tune (Sliders) icon in the top app bar to open the sensitivity slider.
  • Adjust cursor tracking speed from 0.5x (fine precision) to 3.0x (fast velocity).

Quick Action Keys:

  • Quick access buttons for Esc, Tab, Enter, and Backspace (Del).
  • Type Button: Toggles a real-time soft keyboard input bar right above the trackpad.

Tab 2: PC Hardware Keyboard Layout

The PC Keyboard tab provides a full desktop keyboard experience organized into clean sections:

1. Real-Time Soft Keyboard Interceptor

At the top of the PC Keyboard tab is a live typing input box:

  • Tap the input box to open your phone’s on-screen keyboard.
  • Every character you type, paste, or delete is streamed to the target device in real time.
  • There is no need to press a “Send” button.

2. Modifier Keys (With Latch State)

Tap any modifier key once to latch it active for your next keystroke:

  • Ctrl (Control)
  • Alt (Alternate)
  • Shift
  • Win (Windows / Command / Meta key)
  • Esc and Tab

3. Navigation and Editing Block

  • Del (Forward Delete)
  • Ins (Insert)
  • Home and End
  • PgUp (Page Up) and PgDn (Page Down)
  • Enter and Backspace
  • Arrow Keys (Left, Up, Down, Right)

4. Function Keys (F1 - F12)

Dedicated grid for function keys F1 through F12, useful for BIOS menus, terminal shortcuts, and PC desktop applications.

5. Common Desktop Shortcuts

One-tap chips for standard desktop keyboard shortcuts:

  • Ctrl+C (Copy)
  • Ctrl+V (Paste)
  • Ctrl+Z (Undo)
  • Ctrl+A (Select All)
  • Alt+Tab (Switch Windows / Apps)

Screenshot Tool

The Screenshot tool allows you to capture pixel-perfect PNG images of the target device screen over ADB and save them directly to your phone’s storage.

Opening the Screenshot Tool

  1. Open the ADB tab.
  2. Under Built-in Actions, tap the Screenshot tile.
  3. Dioxamine will automatically request a screenshot from the target device and render the preview image.

Tool Controls

1. Taking a Screenshot (Refresh)

  • Tap the Refresh icon in the top app bar to capture a new screenshot at any time.
  • Dioxamine streams raw PNG framebuffer data from the target device and displays the updated image on screen.

2. Saving the Screenshot

  1. Once a screenshot is captured, a Save (Disk) icon appears in the top app bar.
  2. Tap the Save icon.
  3. Your phone’s system document picker will open with a suggested filename (e.g. screenshot_1710000000000.png).
  4. Select your destination folder (e.g. Pictures or Downloads) and tap Save.
  5. A confirmation message will appear confirming the file was saved.

Reboot Menu

The Reboot Menu allows you to safely reboot the target device into various operating modes or completely shut it down without using physical hardware buttons.

Opening the Reboot Menu

  1. Open the ADB tab.
  2. Under Built-in Actions, tap the Reboot tile.

Available Reboot Options

OptionTarget ModeDescription
Reboot SystemAndroid OSNormal reboot back into the Android operating system.
Reboot to BootloaderBootloader (Fastboot)Restarts the device into hardware Bootloader/Fastboot mode for flashing.
Reboot to RecoveryStock / Custom RecoveryRestarts into Android Recovery mode (e.g. Stock Recovery, TWRP, OrangeFox).
Reboot to Fastboot (fastbootd)Userspace FastbootdReboots directly into Android 10+ userspace fastbootd mode to flash dynamic logical partitions.
Shutdown (Power Off)Power OffSafely powers off the target device completely.

Executing a Reboot

  1. Tap on any reboot card (or tap the Play arrow on the right side of the card).
  2. Dioxamine will display a toast confirming execution (e.g. “Executing: Reboot to Recovery”).
  3. The target device will immediately begin its reboot sequence.

Sideload and Rescue Modes

When a target device is connected while in Recovery Sideload mode or Rescue mode, Dioxamine automatically detects the state and presents a dedicated maintenance interface on the main ADB screen.


1. Sideload Mode (Flashing OTA ZIPs)

Recovery Sideload mode is used to flash official OTA update packages, custom ROM zips, Magisk, or custom kernels directly from stock or custom recovery.

When Sideload Mode Appears:

When the target device is in Recovery mode and you select “Apply update from ADB” (or “Advanced > ADB Sideload” in TWRP/OrangeFox), Dioxamine displays a [Sideload] badge on the top device chip and opens the Sideload Flash Screen.

Step-by-Step Instructions:

  1. Connect the target device in Sideload mode via USB OTG cable.
  2. In Dioxamine, tap Choose File.
  3. Select your .zip firmware package (OTA update, ROM, kernel, or Magisk zip) from your phone storage.
  4. Tap Sideload.
  5. Dioxamine will stream the update package to the recovery installer and display:
    • Live percentage progress bar (0% - 100%).
    • Total megabytes transferred (e.g. 1450MB / 2200MB).
  6. When complete, a Complete confirmation will appear. You can tap Done and reboot the target device.

2. Rescue Mode (Wiping Userdata)

Rescue mode is available on certain modern Android devices (such as Google Pixel devices) when booted into Android Rescue Mode.

When Rescue Mode Appears:

When a device is connected in Rescue mode, Dioxamine displays a [Rescue] badge and presents:

  • Sideload OTA Flasher: Allows pushing recovery firmware zips.
  • Wipe Userdata Button: Erases user data partitions to recover from bootloops.

Wiping Userdata in Rescue Mode:

  1. Tap the Wipe Userdata button (outlined in red).
  2. A confirmation dialog will warn you that this action erases all user data on the target device.
  3. Tap Wipe to confirm.
  4. Dioxamine will send the wipe command and output the completion status on screen.

ADB Terminal Shell

Dioxamine includes a full interactive ADB terminal shell that allows you to run Linux shell commands, inspect system logs, and control the target system through standard command-line tools.

Opening the Terminal Shell

  1. Open the ADB tab.
  2. Select the ADB Shell sub-tab at the top.
  3. If an active device is connected, Dioxamine will automatically launch a live shell session and display the command prompt.

Terminal Interface Features

1. Terminal Output View

  • Supports full ANSI color escape codes (color-coded text, syntax highlighting, warnings, and errors).
  • Automatically scrolls with new output while allowing smooth upward touch scrolling to review previous command output.

2. Quick Toolbar Controls

Above the input bar is a utility toolbar:

  • Ctrl Button: Tap to latch the Ctrl key active for your next keystroke. For example, latching Ctrl and sending c will send SIGINT (Ctrl+C) to terminate running processes (like top or logcat).
  • Tab Button: Sends a tab character for shell path and command autocompletion.
  • Clear Button: Clears the current terminal scroll buffer.
  • Restart Button: Closes and restarts the active shell session.

3. Command Input Bar and History

  • Input Field: Type any ADB shell command (e.g. pm list packages, logcat -d, df -h, top).
  • History Navigation (Up / Down Arrows): Tap the up or down arrow icons next to the input field to cycle through your previously executed command history.
  • Send (Enter): Submits the command to the target shell for execution.

Screen Mirroring and Remote Control

Dioxamine integrates the Scrcpy 4.1 engine to provide real-time, low-latency screen mirroring and interactive touch control over Wi-Fi or USB OTG.

Starting Screen Mirroring

  1. Ensure a target device is connected and selected on the ADB tab.
  2. Tap the Scrcpy tab in the bottom navigation bar.
  3. On the Configurator sub-tab, review or adjust your video settings.
  4. Tap the Start Mirroring button at the bottom of the configurator card.
  5. Dioxamine will initialize the mirror session and begin rendering the live video stream in the video player window above.

Interactive Touch and Navigation

While mirroring is active, you can interact directly with the video feed:

  • Touch and Drag: Tapping or dragging on the video player sends real-time multi-touch events directly to the target device screen.
  • Full Screen Mode: Tap the Full Screen icon on the video player overlay to expand the mirror feed to cover your entire phone display. Swipe from the edge or press Back to exit full screen.
  • Floating Navigation Bar: Enable the Floating Navigation Bar in Display settings to overlay quick buttons for:
    • Back: Navigates back one screen.
    • Home: Returns to the home launcher screen.
    • Recents: Opens recent / multitasking apps.
  • Volume Buttons: When the Bind Volume Keys option is enabled, pressing the physical volume up/down buttons on your host phone sends volume adjustments directly to the target device.
  • Turn Screen Off: When enabled, the target device display will remain dark while mirroring is active, saving battery on the target device while allowing you to control it remotely.

Stopping Mirroring

  • Tap the Stop Mirroring button in the configurator, or tap the stop icon in the player controls overlay to terminate the session.

Scrcpy Settings and Quality Tuning

The Configurator sub-tab in Scrcpy provides comprehensive controls to balance visual quality, frame rate, latency, and network bandwidth.


Video Settings

1. Resolution (Max Size)

Caps the maximum dimension of the video stream while preserving the target device’s aspect ratio:

  • 1080p (Default): Balanced sharpness and performance.
  • 720p: Recommended for slower Wi-Fi networks or older devices.
  • 480p: Ultra low bandwidth mode for high latency connections.
  • Auto (Original): Uncapped original device display resolution.
  • Custom Resolution: When enabled in App Settings, tap Add Custom (+) to enter any custom resolution height/width (e.g. 1440 or 1600).

2. Frame Rate (Max FPS)

Limits the video encoder frame rate:

  • 60 FPS (Default): Smooth, fluid animations and scrolling.
  • 30 FPS: Reduces CPU and Wi-Fi load by half.
  • 15 FPS: Low-power monitoring mode.
  • Custom FPS: Enter any custom limit (e.g. 90 or 120 on supported hardware).

3. Video Bitrate

Sets the target compression bitrate:

  • 8 Mbps (Default): High fidelity video output.
  • 4 Mbps: Good balance for standard 2.4GHz Wi-Fi networks.
  • 2 Mbps: Low data usage mode.
  • Custom Bitrate: Enter custom values in Mbps (e.g. 12 or 16).

4. Video Codec

Selects the hardware video encoding format on the target device:

  • H.264 (Default): Compatible with almost all Android devices.
  • H.265 (HEVC): Better compression and quality at lower bitrates, requires hardware HEVC support.
  • AV1: Advanced open-source video compression on modern Android 14+ chipsets.

Audio Settings

Dioxamine supports real-time target device audio forwarding over ADB.

Requirements:

  • Audio forwarding requires the target device to run Android 11 (API 30) or newer.

Options:

  • Forward Device Audio Toggle: Enables real-time audio playback on your host phone speakers or headphones.
  • Audio Codec: Choose between Opus (Default), AAC, FLAC, or uncompressed RAW.
  • Audio Bitrate: Select audio quality: 64 Kbps, 128 Kbps (Default), 192 Kbps, 256 Kbps, or 320 Kbps.
  • Don’t Mute (Audio Duplication):
    • By default, Android mutes the target phone speakers when audio is forwarded.
    • Enabling Don’t Mute plays audio simultaneously on both the target device and host phone.
    • Requires target device to run Android 13 (API 33) or newer.

Camera Streaming Mode

In addition to mirroring the display, Scrcpy allows you to stream live video directly from the target device’s cameras without installing any camera application on the target phone.

Important

Requirement: Camera streaming requires the target device to run Android 12 (API 31) or newer. If a target device running Android 11 or older is selected, Dioxamine will display an API badge (e.g. Requires Android 12+ (API 31). Device is API 30.) and keep the Camera source chip disabled.

Switching to Camera Mode

  1. Open the Scrcpy tab in Dioxamine.
  2. In the Video Source section, tap the Camera chip (available when connected to Android 12+).
  3. Dioxamine will automatically query the target device’s camera hardware (Camera2 API) and list all available sensors.

Camera Configuration Options

1. Camera Selector

  • Pick specific camera sensors on the target device:
    • Back / Main Camera (e.g. Cam 0 (back))
    • Front / Selfie Camera (e.g. Cam 1 (front))
    • Ultra-wide / Telephoto / Macro Sensors (if exposed by vendor)
    • External USB Webcams (e.g. external)

2. Camera Resolution

  • Select from supported hardware resolutions reported by the camera sensor (e.g. 1920x1080, 1280x720, 640x480).

3. Frame Rate and High-Speed 120+ FPS Mode

  • Choose your desired capture frame rate:
    • Standard rates: 60 FPS, 30 FPS, 15 FPS.
    • High-Speed slow motion sensors: 120 FPS, 240 FPS (on supported camera hardware).
    • When high-speed rates (>=120 FPS) are chosen, Dioxamine automatically configures high-speed H.264 camera profiles.

4. Remote Torch / Flashlight Toggle

  • While streaming camera video, tap the Flashlight (Torch) icon in the video player overlay to toggle the target phone’s LED camera flash ON or OFF remotely.

Audio in Camera Mode

When switching Video Source to Camera, Dioxamine automatically defaults the audio source to the target device’s Microphone (mic). This allows using the target phone as a remote webcam and microphone pair for monitoring, streaming, or video calls.

Session Recording and Management

Dioxamine allows you to record live Scrcpy mirroring sessions (both video and audio) directly onto your host device in MP4 format.


Starting a Recording

There are two ways to record a screen mirroring session:

1. Manual Recording

  1. Start a mirroring session from the Scrcpy tab.
  2. Tap on the video player overlay to reveal player controls.
  3. Tap the Record icon (circular button).
  4. The recording starts immediately, and a red REC timer badge (REC 00:15) appears in the top corner indicating elapsed recording duration.
  5. Tap the Stop Record icon (or stop mirroring) to finish and save the clip.

2. Auto-Record Sessions

  1. Navigate to the Settings tab.
  2. Expand the scrcpy settings card.
  3. Toggle on Auto-record sessions (scrcpy_auto_record).
  4. Whenever a screen mirroring session begins, Dioxamine will automatically initiate recording without requiring manual interaction.

Managing and Exporting Recordings

All captured sessions are stored locally and accessible through the Recordings sub-tab in the Scrcpy screen:

  1. Tap the Recordings sub-tab in the top bar of the Scrcpy screen.
  2. View your recorded video items with:
    • File name and timestamp.
    • Total recorded duration.
    • File size.
  3. Exporting (Saving) Clips:
    • Tap the Export (Download) button on any clip.
    • Select a destination folder using Android’s Storage Access Framework (SAF) to save the .mp4 video to your phone’s Gallery, Downloads, or SD card.
  4. Deleting Clips:
    • Tap the Delete (Trash) button.
    • Confirm deletion in the prompt to remove the recording and free up storage.

Technical Notes

  • Container Format: Video and forwarded audio are muxed into standard .mp4 containers.
  • Codec Support: Recording uses the active video codec selected in the Configurator (H.264 or H.265/HEVC). If an unsupported codec configuration is used, a warning banner will inform you.
  • Audio Synchronization: Forwarded device audio (Android 11+) is recorded in sync with the video track.

Scrcpy Logs and Troubleshooting

If screen mirroring fails to start, displays a black screen, or lags, use the built-in Scrcpy Logs viewer to identify the exact cause.

Accessing Scrcpy Logs

  1. Open the Scrcpy tab.
  2. Select the Logs sub-tab next to Configurator.
  3. Dioxamine will display the live log output from the Scrcpy server running on the target device.
  4. Tap the Trash (Clear) icon to clear the current log buffer.

Common Issues and Solutions

1. Mirroring Starts But Screen is Black

  • Cause: The target screen may be locked with secure flags, or a streaming DRM-protected app (e.g. Netflix, banking apps) is in the foreground.
  • Solution: Unlock the target device and return to the home screen.

2. Mirroring Works But Taps Do Not Register (Xiaomi / HyperOS / MIUI)

  • Cause: Xiaomi devices block remote touch input by default until a security toggle is enabled.
  • Solution: On the target device, open Settings > Developer Options and turn ON USB debugging (Security settings).

3. Audio Forwarding Error: “Audio forwarding requires Android 11+”

  • Cause: Audio streaming uses internal Android 11 audio capture APIs. Older devices (Android 10 and below) only support video.
  • Solution: Turn OFF Forward Device Audio in Scrcpy settings for Android 10 or older targets.

4. “Don’t Mute” Error: “Requires at least Android 13”

  • Cause: Duplicating audio to both the target speaker and host phone requires Android 13 (API 33).
  • Solution: Turn OFF Don’t Mute in Audio settings if target device is running Android 11 or 12.

5. High Lag or Stuttering on Wi-Fi

  • Solutions:
    1. Switch video resolution from 1080p to 720p or 480p.
    2. Reduce video bitrate from 8 Mbps to 4 Mbps or 2 Mbps.
    3. Ensure both devices are connected to a 5GHz Wi-Fi network or a 5GHz mobile hotspot rather than 2.4GHz.

Fastboot Getting Started

Dioxamine includes native Fastboot protocol support over USB OTG. This allows you to flash custom partition images, test boot recovery/kernels, manage bootloader lock states, and run raw Fastboot commands directly from your phone.


Fastboot Connection Requirements

  1. USB OTG Connection: Fastboot requires a physical USB OTG cable connection between your host phone and the target device. Fastboot does not operate over Wi-Fi.
  2. Target in Fastboot / Bootloader Mode:
    • Power off the target device.
    • Hold the device’s hardware button combination (typically Power + Volume Down on most devices, or Power + Volume Up on certain models) until the Fastboot/Bootloader screen appears.
    • Alternatively, if the device is currently booted into Android with ADB connected, use Dioxamine’s Reboot Menu > Reboot to Bootloader.

Device Connector Card

At the top of the Fastboot tab:

  • No Device Connected: Displays USB Detector Active • No Fastboot Device Connected while the background USB listener is waiting for a device to be connected.
  • Multiple Device Chips: When one or more devices in Fastboot or Fastbootd mode are plugged in (including multiple devices via a USB-C OTG hub), each device appears as an interactive chip showing its label.
  • Switching Devices: Tap any device chip to immediately switch the active Fastboot session to that target device. The selected device chip is highlighted.
  • Expandable Device List: Tap the expand arrow on the right to view all detected devices, their connection states (Connected or Detected — not connected), and individual Connect / Disconnect buttons.

Sub-Tabs Overview

The Fastboot screen is divided into two primary sub-tabs:

  1. Actions: Guided graphical cards for common maintenance tasks:
    • Reboot Options: Restart to System, Bootloader, Recovery, Fastbootd, Continue Boot, or Shutdown.
    • Flash Image: Flash any partition (boot, recovery, init_boot, vendor_boot, system, etc.) with image files.
    • Boot Image: Temporarily boot a kernel or recovery image without modifying device partitions.
    • Lock State: Unlock or lock bootloader states safely.
    • Variables: Query bootloader variables (e.g. current slot, battery voltage, secure boot status).
  2. Shell: An interactive Fastboot command-line terminal with real-time log output.

Flashing Partition Images

The Flash Image tool in Fastboot allows you to write raw .img image files to any partition on the target device (equivalent to running fastboot flash <partition> <file.img>).

How to Flash an Image

  1. Connect the target device in Fastboot mode via USB OTG.
  2. Tap the Fastboot tab in Dioxamine.
  3. Select the Actions sub-tab.
  4. Tap the Flash Image tile.
  5. Tap Choose Image File.
  6. Your host phone’s file picker will open. Select your .img file (e.g. boot.img, recovery.img, magisk_patched.img, init_boot.img).
  7. Dioxamine will inspect the filename and auto-populate the partition name in a confirmation dialog (e.g. selecting boot.img auto-fills boot).
  8. Review or edit the target partition name:
    • For kernels on Android 13+: init_boot or boot
    • For recovery: recovery or vendor_boot
    • For system images: system
  9. Tap Flash.

Live Progress Tracking

While flashing, Dioxamine displays:

  • Circular progress indicator showing the active flashing operation.
  • Percentage bar (0% to 100%).
  • Byte counter (e.g. 48 MB / 64 MB).
  • Completion Card: Displays a green checkmark upon success, or an error message if the partition is write-protected or invalid.

Warning

Flashing incorrect images to critical partitions can cause your device to fail to boot. Always verify that the image matches your exact device model and processor before flashing.

Live Booting Images (Fastboot Boot)

The Boot Image tool allows you to upload and boot a kernel or custom recovery image in RAM without permanently flashing or modifying your device storage (equivalent to running fastboot boot <image.img>).

Why Use Live Booting?

  • Test Custom Recovery: Test TWRP or OrangeFox without overwriting your stock recovery partition.
  • Rooting via Magisk / KernelSU: Boot a patched boot image once to install Magisk directly to the device.
  • Troubleshooting: Boot a rescue kernel to recover from bootloops.

Step-by-Step Instructions

  1. Ensure the device is connected in Fastboot mode over USB OTG.
  2. In Dioxamine, open Fastboot > Actions > Boot Image.
  3. Tap Choose Image File and Boot.
  4. Select your .img file from phone storage.
  5. Dioxamine will stream the image into the target device RAM and issue the boot execution command.
  6. The target device screen will immediately reboot and launch the selected image in memory.

Note

Live booting requires an unlocked bootloader. Certain newer devices with dynamic vendor boot partitions may require flashing rather than tethered booting depending on manufacturer bootloader implementation.

Bootloader Lock and Unlock State

The Lock State tool in Fastboot allows you to unlock or lock your device bootloader, modify critical partition access, and check unlock abilities.

Accessing Lock State Options

  1. Connect the target device in Fastboot mode via USB OTG.
  2. In Dioxamine, open Fastboot > Actions > Lock State.

Available Lock Actions

ActionCommand ExecutedDescription
Unlock Bootloaderfastboot flashing unlockRequests unlocking the device bootloader to allow flashing custom firmware.
Lock Bootloaderfastboot flashing lockRe-locks the bootloader to restore verified boot and factory security state.
Unlock Critical Partitionsfastboot flashing unlock_criticalUnlocks critical low-level partitions (bootloader, radio, abl, xbl) on supported devices.
Lock Critical Partitionsfastboot flashing lock_criticalRe-locks critical low-level partitions.
Check Unlock Abilityfastboot flashing get_unlock_abilityQueries whether OEM Unlocking is enabled in Developer Options (1 = allowed, 0 = disabled).

Important Warnings

Warning

Unlocking or re-locking the bootloader will trigger a factory reset and erase all user data on the target device due to Android security requirements. Always back up your data before proceeding.

Confirming on Target Device:

When you trigger Unlock Bootloader or Lock Bootloader, the target phone will display an on-screen confirmation prompt (e.g. “Do not unlock bootloader / Unlock the bootloader”). You must use the physical Volume buttons and Power button on the target phone to highlight and confirm the selection.

Fastboot Variables Inspector

The Variables tool queries and displays hardware variables and configuration parameters from the bootloader (equivalent to running fastboot getvar all).

Viewing Variables

  1. Connect the target device in Fastboot mode via USB OTG.
  2. In Dioxamine, navigate to Fastboot > Actions > Variables.
  3. Dioxamine will send the getvar all command and present a list of all exposed variables.

Common Fastboot Variables

VariableDescription
productHardware codename of the target device (e.g. husky, taro, marlin).
current-slotActive A/B boot partition slot (a or b).
slot-countNumber of partition slots supported by the device (2 for A/B devices, 1 for legacy A-only).
unlockedCurrent bootloader state (yes = unlocked, no = locked).
secureIndicates if Secure Boot is active.
battery-voltageCurrent battery voltage in millivolts (useful if device battery is depleted).
max-download-sizeMaximum packet size the bootloader accepts during image flashing in bytes.
version-bootloaderInternal bootloader firmware version string.
version-basebandCellular modem / baseband firmware version string.

UI Controls

  • Refresh (Top Right): Tap the refresh button to re-query the variables from the target device.
  • Copy: Long press on any variable to copy its key and value to your clipboard.

Fastboot Command Shell

The Fastboot Shell provides an interactive command terminal to execute arbitrary Fastboot commands directly on the connected device.

Opening the Fastboot Shell

  1. Open the Fastboot tab in Dioxamine.
  2. Select the Shell sub-tab at the top.
  3. The terminal window will open with a command prompt.

Executing Commands

Type any Fastboot subcommand into the bottom input bar (without typing the word fastboot) and tap Send (or press Enter on your keyboard):

Example Commands:

  • getvar product: Check the device codename.
  • oem device-info: Check OEM-specific bootloader lock details on older devices.
  • set_active a / set_active b: Switch active A/B boot slots.
  • erase userdata: Wipe the user data partition.
  • reboot: Reboot into the Android system.
  • reboot-bootloader: Restart back into Fastboot mode.
  • reboot-fastboot: Reboot into userspace fastbootd mode.

Log Output and Status Colors

Each response line in the log window is color-coded:

  • $ [command] (Primary Color): Command sent to device.
  • [output] (White/Gray): Text output or info packets returned by the bootloader.
  • ! [error] (Red): Fastboot errors (e.g. FAIL: remote: Partition not found).
  • # [system] (Teal): Connection lifecycle notices (e.g. USB attached, session opened).

Toolbar Controls

  • Clear Log: Tap the Delete Sweep icon in the top right to clear the terminal output history.
  • Auto Scroll: The terminal automatically scrolls to the newest line upon receiving new data.

ADB Key Management

ADB requires an RSA cryptographic keypair to authenticate connections with target Android devices. Dioxamine generates and manages its own internal ADB keypair securely within the app.

Accessing ADB Key Settings

  1. Tap the Settings tab in the bottom navigation bar.
  2. Tap on the ADB Key expandable card.

Key Management Options

1. Viewing Key Fingerprint

  • Dioxamine displays the SHA-256 fingerprint of your active public RSA key (e.g. SHA256:abcd1234...).
  • When connecting to a target device for the first time, this fingerprint matches the prompt shown on the target phone screen.

2. Regenerate Key Pair

  • Tap Regenerate Key to delete the current keypair and create a fresh 2048-bit RSA key.
  • When to use: If an unauthorized device has whitelisted your key, or if you wish to reset trust on all previously paired devices.
  • After regenerating, all target devices will prompt to re-authorize the connection when plugged in.

3. Load Custom Key (Import)

  • Tap Load Custom Key to import an existing adbkey private key file from your phone storage (for example, copied from your PC’s ~/.android/adbkey).
  • Why use this: Allows Dioxamine to connect to devices that already trust your PC without showing the authorization prompt again.

4. Export Key (Backup)

  • Tap Export Key to save your active private adbkey file to your phone’s storage.
  • Useful for creating backups or migrating your authorization key to another phone.

Appearance and Language

Dioxamine supports Material 3 styling, dynamic wallpaper coloring (Monet), and flexible dark/light theme preferences.

Accessing Theme Settings

  1. Open the Settings tab.
  2. Tap the Theme Settings expandable card.

Theme Options

1. Dynamic Colors (Material You / Monet)

  • Toggle Switch: When enabled on Android 12 or newer, Dioxamine generates its color palette dynamically from your current system wallpaper.
  • If disabled (or on Android 11 and older), Dioxamine uses its default modern Material 3 color theme.

2. Theme Mode Selection

Choose your preferred theme display mode:

  • System Default (Default): Automatically follows your phone’s system dark/light mode schedule.
  • Light Theme: Forces bright, high-contrast light colors.
  • Dark Theme: Uses deep dark backgrounds optimized for dark environments.
  • AMOLED: True pure black (#000000) surfaces designed for maximum battery savings on OLED/AMOLED displays.

Language Settings

  1. In the Settings tab, tap the Language expandable card.
  2. Choose from:
    • System Default: Automatically matches your Android device system locale.
    • English (en): Forces English across all menus and dialogs.
    • Simplified Chinese (zh-CN / 简体中文): Chinese localization.
    • Hindi (hi / हिन्दी): Hindi localization.
  3. Tap Contribute to translation to view guidelines on submitting new translations for your language.

Miscellaneous and Keep Alive

The Miscellaneous card in Settings provides tools to keep Dioxamine connections alive and active in the background when the app is minimized.


Keep Alive Background Service

By default, modern Android versions (Android 11+) apply aggressive background limits, including the Cached Apps Freezer and Doze Mode. If an app is minimized without a Foreground Service, the operating system pauses CPU execution, freezing active ADB TCP/USB sockets and fastboot operations.

The Keep Alive feature resolves this by running a dedicated Android Foreground Service with a WakeLock.


Enabling Keep Alive

  1. Open the Settings tab.
  2. Tap the Miscellaneous expandable card.
  3. Toggle on Keep Alive.
  4. Grant the requested system permissions:
    • Notification Permission (POST_NOTIFICATIONS on Android 13+ / API 33+): Required to show the persistent foreground service notification.
    • Battery Optimization Exemption (Android 6.0+ / API 23+): Prompts you to exempt Dioxamine from battery optimizations to prevent Doze mode from sleeping background network/USB transfers.

Live Status Notification

While Keep Alive is running, Dioxamine displays an ongoing notification in your notification shade showing real-time connected device metrics:

  • Both ADB and Fastboot connected: e.g., 1 ADB device connected, 1 Fastboot device connected
  • ADB Only: e.g., 1 ADB device connected or 2 ADB devices connected
  • Fastboot Only: e.g., 1 Fastboot device connected
  • No devices connected: No devices connected • Active in background

Notification Actions

  • Tap Notification: Instantly brings Dioxamine back to the foreground.
  • Stop Action: Tap the Stop button directly on the notification to terminate the background service and release the WakeLock without needing to navigate to the Settings tab.

Under Settings > About, you can find direct links to external resources:

Application Logs and Bug Reporting

Dioxamine maintains an internal diagnostic log system to assist with troubleshooting connection errors, Scrcpy streaming issues, Fastboot flashing failures, and plugin execution bugs.

Accessing Log Settings

  1. Open the Settings tab.
  2. Tap the Logs expandable card.

Log Settings Options

1. Enable Logging Toggle

  • Toggle Switch: Enables or disables background diagnostics logging.
  • Enabled by default to record session events and error traces.

2. Export All Logs (ZIP Archive)

  1. Tap Export All Logs.
  2. Your phone’s system document picker will open with a suggested ZIP filename (e.g. dioxamine_logs_1710000000000.zip).
  3. Select your save directory and tap Save.
  4. The generated ZIP file contains complete timestamps and error backtraces. You can share this ZIP file on the official Telegram support channel or attach it to a GitHub issue.

3. Clear All Logs

  • Tap Clear Logs (outlined in red) to permanently erase all locally cached log records and reclaim storage space.

Plugin Security and Permissions

Dioxamine provides a secure sandbox environment for third-party Web plugins with granular permission gates and developer debugging tools.

Accessing Plugin Settings

  1. Open the Settings tab.
  2. Tap the Plugin Settings expandable card.

Plugin Security Options

1. WebView Debugging Toggle

  • Toggle Switch: Enables Chrome Remote DevTools inspection for installed plugins.
  • For Plugin Developers: When enabled, you can connect your host phone to a PC, open chrome://inspect in Google Chrome on your computer, and inspect plugin DOM, console logs, network calls, and JavaScript breakpoints in real time.

2. Manage Plugin Permissions

Dioxamine requires user authorization before any plugin can execute shell commands, read device info, push files, or forward ports.

  1. In the Plugin Settings card, tap Manage Permissions.
  2. A list of all installed plugins will be displayed along with their requested permissions (e.g. device.read, shell.exec, files.manage, saf.pick).
  3. You can review permission statuses:
    • Allowed Always: Granted permanent permission.
    • Ask Every Time: Prompts every time the plugin triggers an action.
    • Denied: Blocks the plugin from accessing that capability.
  4. Tap Revoke or change permissions individually for any plugin at any time.

Plugin Architecture and Overview

Dioxamine provides a modern, sandboxed Web Plugin System. Developers can create rich tools, dashboards, terminals, and utilities using standard web technologies (HTML, CSS, JavaScript, WebAssembly) that interact directly with connected ADB devices through a secure native bridge.

Core Concepts

A Dioxamine plugin is a directory or ZIP package containing:

  • plugin.json: The manifest file describing identity, version, entrypoint, required permissions, and display settings.
  • index.html (or custom entry): The main web page for the plugin interface.
  • Web assets: CSS styles, JavaScript logic, icons, fonts, WebAssembly binaries, or static assets.
my-plugin/
├── plugin.json
├── index.html
├── styles.css
├── app.js
└── icon.png

Security and Sandboxing

Plugins operate under strict security boundaries:

  1. Origin Isolation via WebViewAssetLoader: Plugins are loaded over a virtual secure origin (https://appassets.androidplatform.net/plugin/). Direct file:// access is disabled in the Android WebView, preventing cross-origin leaks and unauthorized local filesystem access.
  2. Permission Gating: Dangerous ADB capabilities (such as shell execution, file push/pull, package installation, and port forwarding) are restricted behind explicit permissions. When a plugin attempts an action, Dioxamine prompts the user for consent and enforces policy rules.
  3. No External Network Leaks: Requests to external domains are blocked by the native WebViewClient unless explicitly configured.
  4. Path Traversal Protection: The native asset loader enforces canonical path checking, preventing plugins from escaping their allocated storage directory.

Communication Bridge

When Dioxamine loads a plugin, it automatically injects a JavaScript bridge script before any page scripts execute:

<script src="https://appassets.androidplatform.net/assets/plugin_runtime/dioxamine-bridge.js"></script>

This exposes the global object window.dioxamine (and window.Dioxamine), which provides asynchronous Promise-based APIs for device interactions, interactive shell streams, storage access, native dialogs, and dynamic theming.

Quickstart: Your First Plugin

In this tutorial, you will create a simple plugin called Device Info that displays the connected Android device’s model and kernel version using single-command shell execution.

Step 1: Create the Plugin Manifest

Create a new directory named device-info-plugin and add a plugin.json file:

{
  "schemaVersion": 1,
  "id": "com.example.deviceinfo",
  "name": "Device Info",
  "description": "Displays device model and kernel information",
  "version": "1.0.0",
  "versionCode": 1,
  "author": "Your Name",
  "entry": "index.html",
  "icon": "icon.png",
  "minAppVersionCode": 1,
  "permissions": [
    "shell"
  ],
  "fullscreen": false
}

Step 2: Create the User Interface (index.html)

Create index.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
    <title>Device Info</title>
    <link rel="stylesheet" href="styles.css">
</head>
<body>
    <div id="app">
        <h1>Device Information</h1>
        <p class="subtitle">Powered by Dioxamine Plugin Engine</p>

        <div class="card">
            <div class="row">
                <span class="label">Model:</span>
                <span id="device-model" class="value">Loading...</span>
            </div>
            <div class="row">
                <span class="label">Kernel:</span>
                <span id="kernel-version" class="value">Loading...</span>
            </div>
        </div>

        <button id="refresh-btn">Refresh</button>
    </div>

    <script src="app.js"></script>
</body>
</html>

Step 3: Add Styles (styles.css)

Create styles.css using Dioxamine CSS theme variables:

body {
    margin: 0;
    padding: 16px;
    background-color: var(--dioxamine-bg, #121212);
    color: var(--dioxamine-fg, #ffffff);
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
}

#app {
    max-width: 600px;
    margin: 0 auto;
}

h1 {
    font-size: 20px;
    margin-bottom: 4px;
}

.subtitle {
    font-size: 13px;
    color: var(--dioxamine-on-surface-variant, #888888);
    margin-bottom: 20px;
}

.card {
    background-color: var(--dioxamine-card-bg, #1e1e1e);
    border: 1px solid var(--dioxamine-outline-variant, #333333);
    border-radius: 12px;
    padding: 16px;
    margin-bottom: 16px;
}

.row {
    display: flex;
    justify-content: space-between;
    padding: 8px 0;
    border-bottom: 1px solid var(--dioxamine-outline-variant, #2a2a2a);
}

.row:last-child {
    border-bottom: none;
}

.label {
    font-weight: 500;
    color: var(--dioxamine-on-surface-variant, #aaaaaa);
}

.value {
    font-family: monospace;
    color: var(--dioxamine-accent, #64b5f6);
}

button {
    background-color: var(--dioxamine-primary, #2196f3);
    color: var(--dioxamine-on-primary, #ffffff);
    border: none;
    border-radius: 8px;
    padding: 10px 18px;
    font-size: 14px;
    font-weight: 600;
    cursor: pointer;
    width: 100%;
}

button:active {
    opacity: 0.85;
}

Step 4: Implement Logic (app.js)

Create app.js and use dioxamine.shellExec() to query Android system properties:

async function loadDeviceInfo() {
    const modelEl = document.getElementById('device-model');
    const kernelEl = document.getElementById('kernel-version');

    modelEl.textContent = 'Fetching...';
    kernelEl.textContent = 'Fetching...';

    try {
        // Verify bridge and active connection
        const device = await dioxamine.getActiveDevice();
        if (!device) {
            modelEl.textContent = 'No connected ADB device';
            kernelEl.textContent = '-';
            return;
        }

        // Query model
        const modelResult = await dioxamine.shellExec('getprop ro.product.model');
        modelEl.textContent = modelResult.stdout.trim() || 'Unknown';

        // Query kernel
        const kernelResult = await dioxamine.shellExec('uname -r');
        kernelEl.textContent = kernelResult.stdout.trim() || 'Unknown';

        dioxamine.showToast('Device information updated', 'short');
    } catch (error) {
        modelEl.textContent = 'Error: ' + error.message;
        kernelEl.textContent = '-';
        dioxamine.log.e('DeviceInfo', error.message);
    }
}

document.getElementById('refresh-btn').addEventListener('click', loadDeviceInfo);

// Wait for Dioxamine bridge initialization
if (window.dioxamine && window.__dioxamine_bridge_ready) {
    loadDeviceInfo();
} else {
    window.addEventListener('dioxamine-bridge-ready', loadDeviceInfo, { once: true });
}

Step 5: Package and Install

  1. Create a 512x512 PNG image named icon.png.
  2. Select all files inside the directory (plugin.json, index.html, styles.css, app.js, icon.png) and create a ZIP archive named com.example.deviceinfo.zip.
  3. In Dioxamine, navigate to the ADB tab, click Plugins, click Install Plugin, and select your ZIP file.
  4. Grant the requested shell permission when prompted, and your plugin will run.

Manifest Specification (plugin.json)

Every Dioxamine plugin must include a valid plugin.json file at the root of its archive. The manifest declares metadata, required permissions, versioning, and display preferences.

Example Manifest

{
  "schemaVersion": 1,
  "id": "com.rhythmcache.dioxamine.terminal",
  "name": "Terminal",
  "description": "Interactive PTY terminal using xterm.js",
  "version": "1.0.1",
  "versionCode": 2,
  "author": "RhythmCache",
  "entry": "index.html",
  "icon": "icon.png",
  "minAppVersionCode": 1,
  "permissions": [
    "shell"
  ],
  "fullscreen": true,
  "homepage": "https://github.com/rhythmcache/dioxamine"
}

Field Reference

FieldTypeRequiredDescription
schemaVersionIntegerYesManifest format version. Must currently be 1.
idStringYesUnique reverse-DNS identifier (lowercase letters, numbers, dots, and underscores). Must contain at least one dot (for example, com.example.myplugin).
nameStringYesHuman-readable title displayed in the plugin directory and header. Maximum 50 characters.
descriptionStringNoShort summary of plugin functionality. Maximum 200 characters. Default: "".
versionStringYesHuman-readable version string (for example, "1.0.0" or "2.1.0-beta").
versionCodeIntegerYesIncremental integer version used for upgrade detection. Must be greater than or equal to 1.
authorStringNoAuthor or organization name.
entryStringYesRelative path to the HTML entrypoint file (for example, "index.html" or "ui/main.html"). Path traversal (..) is forbidden.
iconStringNoRelative path to the plugin icon image (PNG, WebP, JPG, or SVG). Default: null.
minAppVersionCodeIntegerNoMinimum Dioxamine app versionCode required to execute this plugin. Default: 1.
permissionsArray<String>NoList of required permission identifiers. Only valid permission names are permitted. Default: [].
fullscreenBooleanNoIf true, hides the Dioxamine top bar on launch to provide an edge-to-edge full-screen display. Default: false.
homepageStringNoWeb URL pointing to the plugin repository, source code, or documentation.

Validation Rules

When installing or loading a plugin, Dioxamine strictly enforces the following validation checks:

  1. ID Format:
    • Must match the regular expression ^[a-z0-9]+(\.[a-z0-9_]+)+$.
    • Uppercase characters, spaces, and leading/trailing dots will cause installation to fail.
  2. Path Sanitization:
    • entry and icon paths must point inside the plugin directory.
    • Any path containing .. or leading slashes will be rejected.
  3. Permission Whitelist:
    • Every entry in permissions must be one of the recognized permission strings: shell, push, pull, install, forward, reverse.
    • Unknown permissions will fail manifest validation with an explicit error.
  4. App Version Compatibility:
    • If minAppVersionCode exceeds the running Dioxamine application version, installation will be blocked with a compatibility notice.

Permissions and Security Model

Dioxamine enforces a strict permission model to protect connected devices and the host Android system from unauthorized operations.

Declared Permissions

Plugins must explicitly declare every required capability in plugin.json. Attempting to call an API without declaring the corresponding permission results in an immediate Promise rejection with SecurityException: Permission not declared in manifest.

PermissionIdentifierDescriptionProtected APIs
Shell Execution"shell"Allows executing non-interactive shell commands and opening interactive PTY/sh sessions.dioxamine.shellExec(), dioxamine.openInteractiveShell()
File Push"push"Allows writing and pushing files or streams onto the target device filesystem.dioxamine.pushFile(), dioxamine.pushStream()
File Pull"pull"Allows reading and pulling files or directories from the target device filesystem.dioxamine.pullFile(), dioxamine.pullStream()
Package Install"install"Allows streaming APK files to the device package manager (pm install).dioxamine.installApk()
Port Forward"forward"Allows binding local host ports and forwarding traffic to target device sockets.dioxamine.forwardPort(), dioxamine.forwardList(), dioxamine.forwardRemove()
Port Reverse"reverse"Allows binding target device ports and reversing traffic back to the host system.dioxamine.reversePort(), dioxamine.reverseList(), dioxamine.reverseRemove()

Permission Policies

When a plugin is executed, Dioxamine evaluates permission requests using a configurable policy:

  1. PROMPT (Default):
    • On the first call to a privileged API, Dioxamine pauses execution and presents a native consent dialog to the user.
    • The user can choose:
      • Allow Once: Grants permission for the current session only.
      • Always Allow: Persists granted permission in the secure app store.
      • Deny: Rejects the immediate call and records denial.
  2. ALWAYS_ALLOW:
    • The user has permanently granted the permission for this specific plugin ID.
    • API calls execute immediately without prompts.
  3. ALWAYS_DENY:
    • The user has permanently blocked the permission for this plugin.
    • API calls fail immediately with Permission denied by user policy.

Managing and Revoking Permissions in App Settings

Users can view, grant, or revoke permissions at any time:

  1. Open Dioxamine and go to the Settings tab.
  2. Expand the Plugins card.
  3. Tap Manage next to Plugin Permissions.
  4. Adjust policies individually for each installed plugin (Ask Every Time, Always Allow, or Always Deny), or tap Reset All to restore default prompt behavior.

Safe Native APIs (No Permission Required)

The following bridge methods are safe UI/context utilities and do not require declared permissions:

  • dioxamine.getActiveDevice()
  • dioxamine.showToast()
  • dioxamine.showDialog()
  • dioxamine.setFullScreen() / dioxamine.fullScreen()
  • dioxamine.pickFile() / dioxamine.saveFile() (delegates to Android Storage Access Framework with user file picker)
  • dioxamine.log.* and console.* forwarding
  • dioxamine.getTheme() and dioxamine.onThemeChange()
  • Base64 / UTF-8 conversion helpers

Layout Patterns and CSS Guide

Because Dioxamine renders plugins within an Android WebView inside Jetpack Compose, understanding how CSS containing blocks resolve height is essential for creating responsive interfaces.

Pattern A: Full-Screen App and Terminal Layout

Use this pattern for interactive terminals, real-time log viewers, code editors, or canvas games where the page should occupy the entire screen, lock document scrolling, and manage an internal scrolling panel.

/* Lock root document to exact physical viewport boundaries */
html, body {
    width: 100%;
    height: 100%;
    margin: 0;
    padding: 0;
    overflow: hidden;
    background-color: var(--dioxamine-bg, #121212);
    color: var(--dioxamine-fg, #ffffff);
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
}

/* Root application flex container */
#app {
    display: flex;
    flex-direction: column;
    width: 100%;
    height: 100%;
    overflow: hidden;
}

/* Fixed toolbar or header */
header {
    flex-shrink: 0;
    padding: 10px 14px;
    background-color: var(--dioxamine-card-bg, #1e1e1e);
    border-bottom: 1px solid var(--dioxamine-outline-variant, #333333);
}

/* Main scrollable viewport (terminal / log container) */
.scroll-content {
    flex: 1 1 0;
    min-height: 0; /* CRITICAL: Allows flex child to shrink below intrinsic content size */
    overflow-y: auto;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    padding: 12px;
}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
    <link rel="stylesheet" href="styles.css">
</head>
<body>
    <div id="app">
        <header>
            <h1>Terminal Console</h1>
        </header>
        <div id="terminal-container" class="scroll-content"></div>
    </div>
</body>
</html>

Pattern B: Standard Document and Page Layout

Use this pattern for information dashboards, settings pages, documentation readers, or card-based views that scroll naturally.

body {
    margin: 0;
    padding: 16px;
    background-color: var(--dioxamine-bg, #121212);
    color: var(--dioxamine-fg, #ffffff);
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
    -webkit-text-size-adjust: 100%;
}

.container {
    max-width: 720px;
    margin: 0 auto;
}

.card {
    background-color: var(--dioxamine-card-bg, #1e1e1e);
    color: var(--dioxamine-card-fg, #ffffff);
    border: 1px solid var(--dioxamine-outline-variant, #333333);
    border-radius: 12px;
    padding: 16px;
    margin-bottom: 16px;
}

High-Frequency DOM Updates Best Practice

When processing high-frequency streams (such as logcat or serial metrics emitting hundreds of lines per second), appending single DOM elements synchronously blocks the UI thread.

Always batch DOM insertions using DocumentFragment and a throttled render loop:

let pendingBatch = [];
let renderTimer = null;
const MAX_LINES = 1000;

function queueLine(text) {
    pendingBatch.push(text);
    if (!renderTimer) {
        renderTimer = setTimeout(flushBatch, 40); // 25fps batch flush
    }
}

function flushBatch() {
    renderTimer = null;
    if (pendingBatch.length === 0) return;

    const container = document.getElementById('log-container');
    const fragment = document.createDocumentFragment();
    const batch = pendingBatch.splice(0, pendingBatch.length);

    for (let i = 0; i < batch.length; i++) {
        const line = document.createElement('div');
        line.className = 'log-line';
        line.textContent = batch[i];
        fragment.appendChild(line);
    }

    container.appendChild(fragment);

    // Prune excess lines to prevent memory bloat
    while (container.childNodes.length > MAX_LINES) {
        container.removeChild(container.firstChild);
    }

    // Smooth auto-scroll
    container.scrollTop = container.scrollHeight;
}

JavaScript Bridge API Reference

The global dioxamine object provides asynchronous methods for interacting with connected devices, native dialogs, file systems, and the Android host.

Bridge Initialization

The native bridge is loaded automatically before any plugin scripts execute. To guarantee readiness across all initialization states, listen for the dioxamine-bridge-ready event:

function initPlugin() {
    console.log("Dioxamine Bridge is ready:", window.dioxamine);
}

if (window.dioxamine && window.__dioxamine_bridge_ready) {
    initPlugin();
} else {
    window.addEventListener('dioxamine-bridge-ready', initPlugin, { once: true });
}

API Modules

The API is organized into the following specialized modules:

  1. Device Management: Query the active ADB connection and metadata.
  2. Single Command Execution (shellExec): Run non-interactive commands and receive exit code, stdout, and stderr.
  3. Interactive Shell Sessions (openInteractiveShell): Open persistent bi-directional PTY streams for terminals and live logcat.
  4. File Operations: Push and pull files, stream raw data, install APK packages, and launch Android SAF file pickers.
  5. Port Forwarding and Reverse: Manage TCP socket forwarding and reversing.
  6. UI Controls, Dialogs and Fullscreen: Show native Material toasts, blocking dialogs, and toggle edge-to-edge full-screen mode.
  7. Native Logging and Debugging: Forward logs and console output directly to Android Logcat.
  8. Dynamic Theming and Material 3: Integrate with Dioxamine’s dynamic color schemes and listen for theme changes.

Device Management API

The Device Management API allows plugins to verify the current ADB connection status and query device identifiers.

dioxamine.getActiveDevice()

Retrieves information about the currently active ADB device.

Signature

dioxamine.getActiveDevice(): Promise<DeviceInfo | null>

Parameters

None.

Returns

A Promise resolving to a DeviceInfo object, or null if no device is connected.

DeviceInfo Object Structure

interface DeviceInfo {
    serial: string;      // Device serial or IP:Port (e.g. "192.168.1.50:5555" or "RFCW10ABCDE")
    model: string;       // Device marketing name or model (e.g. "Pixel 8 Pro")
    state: string;       // Connection state: "device", "offline", "unauthorized", etc.
}

Example

async function checkDevice() {
    const dev = await dioxamine.getActiveDevice();
    if (!dev) {
        console.warn("No active ADB device connected in Dioxamine");
        return;
    }
    console.log(`Connected to ${dev.model} (${dev.serial}) [${dev.state}]`);
}

Single Command Execution (shellExec)

The shellExec API runs a non-interactive shell command on the connected ADB device, captures the full output stream, and returns the exit code, standard output, and standard error.

Required Permission: "shell"

dioxamine.shellExec()

Executes a command string synchronously on the target device shell.

Signature

dioxamine.shellExec(command: string): Promise<ShellExecResult>

Parameters

  • command (string): The shell command line to execute (for example, "getprop ro.build.version.release" or "pm list packages -3").

Returns

A Promise resolving to a ShellExecResult object:

interface ShellExecResult {
    stdout: string;      // Standard output content
    stderr: string;      // Standard error content
    exitCode: number;    // Process exit code (0 indicates success)
}

Errors

  • Rejects if the "shell" permission was not declared in plugin.json.
  • Rejects if the user denies the permission prompt.
  • Rejects if no device is connected.

Example

async function getBatteryLevel() {
    try {
        const result = await dioxamine.shellExec("dumpsys battery | grep level");
        if (result.exitCode === 0) {
            const match = result.stdout.match(/level:\s*(\d+)/);
            if (match) {
                console.log("Battery level: " + match[1] + "%");
            }
        } else {
            console.error("Command failed with stderr:", result.stderr);
        }
    } catch (err) {
        console.error("Shell error:", err.message);
    }
}

Interactive Shell Sessions (openInteractiveShell)

The Interactive Shell API opens a persistent bi-directional ADB streaming session. This is designed for terminal emulators (such as xterm.js), interactive command prompts (sh), and continuous background log streamers (logcat -v time -T 25).

Required Permission: "shell"

dioxamine.openInteractiveShell()

Opens a live interactive PTY shell stream to the target device.

Signature

dioxamine.openInteractiveShell(): Promise<InteractiveShellSession>

Parameters

None.

Returns

A Promise resolving to an InteractiveShellSession controller object.


InteractiveShellSession Interface

interface InteractiveShellSession {
    sessionId: string;
    
    // Register incoming binary data callback (data is base64 encoded)
    onData(callback: (base64Chunk: string) => void): void;
    
    // Register stream termination callback
    onClose(callback: (error?: string) => void): void;
    
    // Send binary data into the shell stream (data must be base64 encoded)
    write(base64Data: string): Promise<void>;
    
    // Dynamically resize target device PTY dimensions (triggers SIGWINCH on device)
    resize(cols: number, rows: number): Promise<void>;
    
    // Terminate the shell session and close native socket
    close(): Promise<void>;
}

Dynamic Window Sizing (session.resize)

Interactive full-screen CLI apps (like nano, htop, vim, and top) rely on the Linux kernel PTY dimensions (struct winsize) to layout their interface correctly.

When running inside a responsive WebView, whenever the terminal size changes (such as on screen rotation, split-screen, or when the virtual keyboard appears), call session.resize(cols, rows).

  • cols: Number of columns (positive integer, 1..65535).
  • rows: Number of rows (positive integer, 1..65535).

This sends an official ADB Shell v2 WINDOW_SIZE_CHANGE packet to the Android daemon, which executes ioctl(pty_fd, TIOCSWINSZ) and broadcasts SIGWINCH to the running command.


Encoding and Decoding Data

Data transmitted over onData and write is encoded in Base64 to support arbitrary binary streams, ANSI escape codes, and UTF-8 multibyte characters safely.

You can use the built-in helper functions dioxamine.utf8ToBase64() and dioxamine.base64ToUtf8() or standard Web APIs (TextEncoder/TextDecoder):

// Converting String -> Base64 for session.write()
function stringToBase64(str) {
    const bytes = new TextEncoder().encode(str);
    let bin = '';
    for (let i = 0; i < bytes.length; i++) bin += String.fromCharCode(bytes[i]);
    return btoa(bin);
}

// Converting Base64 -> String from session.onData()
function base64ToString(b64) {
    const bin = atob(b64);
    const bytes = new Uint8Array(bin.length);
    for (let i = 0; i < bin.length; i++) bytes[i] = bin.charCodeAt(i);
    return new TextDecoder('utf-8', { fatal: false }).decode(bytes);
}

Example 1: Integrating with xterm.js & FitAddon

const term = new Terminal({
    cursorBlink: true,
    fontFamily: 'monospace',
    theme: { background: '#121212', foreground: '#ffffff' }
});

const fitAddon = new FitAddon.FitAddon();
term.loadAddon(fitAddon);

term.open(document.getElementById('terminal-container'));
fitAddon.fit();

async function startTerminal() {
    const session = await dioxamine.openInteractiveShell();

    // Send initial dimensions
    session.resize(term.cols, term.rows);

    // Device stdout -> xterm.js
    session.onData((b64) => {
        const text = dioxamine.base64ToUtf8(b64);
        term.write(text);
    });

    // Keyboard input -> Device stdin
    term.onData((data) => {
        session.write(dioxamine.utf8ToBase64(data));
    });

    // Dynamic resizing (device rotation / soft keyboard toggling)
    term.onResize(({ cols, rows }) => {
        session.resize(cols, rows);
    });

    window.addEventListener('resize', () => {
        fitAddon.fit();
    });

    session.onClose((err) => {
        term.writeln("\r\n[Session Terminated: " + (err || "OK") + "]");
    });
}

Example 2: Continuous Logcat Stream

async function startLiveLogcat(onLineReceived) {
    const session = await dioxamine.openInteractiveShell();
    let buffer = '';

    session.onData((b64) => {
        buffer += dioxamine.base64ToUtf8(b64);
        const lines = buffer.split('\n');
        buffer = lines.pop(); // keep trailing partial line

        for (let i = 0; i < lines.length; i++) {
            const line = lines[i].trimEnd();
            if (line) onLineReceived(line);
        }
    });

    // Send command to follow the last 25 lines continuously (-T)
    const cmd = "logcat -v time -T 25\n";
    await session.write(dioxamine.utf8ToBase64(cmd));
    return session;
}

File Operations and Storage API

Dioxamine provides methods to push and pull files between the host and connected device, stream APKs to the Android package manager, and access local device storage via Android Storage Access Framework (SAF).

dioxamine.pushFile()

Uploads a base64-encoded file directly to a remote path on the connected device.

Required Permission: "push"

Signature

dioxamine.pushFile(remotePath: string, base64Data: string, mode?: number): Promise<void>

Parameters

  • remotePath (string): Target path on the connected device (for example, "/sdcard/Download/script.sh").
  • base64Data (string): File contents encoded in base64.
  • mode (number, optional): POSIX file permission mode (for example, 0o755 for executables). Default: 0o644.

dioxamine.pullFile()

Downloads a file from the connected device and returns its contents as base64.

Required Permission: "pull"

Signature

dioxamine.pullFile(remotePath: string): Promise<string>

Parameters

  • remotePath (string): Source file path on the connected device (for example, "/sdcard/Download/screencap.png").

Returns

A Promise resolving to the base64-encoded string of the file contents.


dioxamine.installApk()

Streams an APK package to the target device and invokes pm install.

Required Permission: "install"

Signature

dioxamine.installApk(base64ApkData: string, flags?: string[]): Promise<string>

Parameters

  • base64ApkData (string): Binary APK file encoded in base64.
  • flags (string[], optional): Array of installation arguments (for example, ["-r", "-d", "-g"]).

Returns

A Promise resolving to the package manager installation output (for example, "Success").


Storage Access Framework (SAF) File Pickers

Because plugins run in a sandboxed WebView, they cannot directly read the host phone filesystem. Dioxamine bridges Android’s native system file picker dialogs.

No special manifest permission is required for SAF pickers.

dioxamine.pickFile()

Opens the system document picker for the user to select a file from host phone storage.

dioxamine.pickFile(options?: { mimeType?: string }): Promise<SelectedFile | null>
interface SelectedFile {
    name: string;        // File name (e.g. "update.zip")
    size: number;        // Size in bytes
    mimeType: string;    // MIME type
    base64Data: string;  // File content in base64
}

dioxamine.saveFile()

Opens the system save-file dialog for the user to export a file to host phone storage.

dioxamine.saveFile(options: {
    fileName: string;
    mimeType?: string;
    base64Data: string;
}): Promise<boolean>

Port Forwarding and Reverse API

The Port Forwarding and Reverse API allows plugins to route TCP network traffic between the host Android device and the target ADB device.

Port Forwarding (adb forward)

Forwarding redirects connections made to a socket on the host to a socket on the connected device.

Required Permission: "forward"

dioxamine.forwardPort()

Binds a local host socket and routes incoming connections to a remote target socket.

dioxamine.forwardPort(local: string, remote: string): Promise<void>

Parameters:

  • local (string): Local host specification (for example, "tcp:8080").
  • remote (string): Remote device specification (for example, "tcp:8080" or "localabstract:scrcpy").

dioxamine.forwardList()

Lists all active port forward rules created by the session.

dioxamine.forwardList(): Promise<Array<{ local: string, remote: string }>>

dioxamine.forwardRemove()

Removes an active port forward binding.

dioxamine.forwardRemove(local: string): Promise<void>

Port Reverse (adb reverse)

Reversing redirects connections made to a socket on the connected device back to a socket on the host device.

Required Permission: "reverse"

dioxamine.reversePort()

Binds a remote device socket and routes connections back to a local host socket.

dioxamine.reversePort(remote: string, local: string): Promise<void>

Parameters:

  • remote (string): Remote device specification (for example, "tcp:3000").
  • local (string): Local host specification (for example, "tcp:3000").

dioxamine.reverseList()

Lists all active reverse rules.

dioxamine.reverseList(): Promise<Array<{ remote: string, local: string }>>

dioxamine.reverseRemove()

Removes an active reverse socket binding.

dioxamine.reverseRemove(remote: string): Promise<void>

Automatic Session Cleanup

All port forward and reverse mappings created during a plugin session are automatically closed and cleaned up by the native runtime when the plugin is closed or disposed.

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.

Native Logging and Debugging

Dioxamine provides integrated logging channels that bridge JavaScript console messages and explicit log calls directly into the native Android Logcat stream.


Direct Native Logging (dioxamine.log)

The dioxamine.log namespace sends structured log entries to Android Logcat under the tag Plugin:<plugin-id>/<tag>.

Methods

dioxamine.log.v(tag: string, message: string): void  // Verbose
dioxamine.log.d(tag: string, message: string): void  // Debug
dioxamine.log.i(tag: string, message: string): void  // Info
dioxamine.log.w(tag: string, message: string): void  // Warn
dioxamine.log.e(tag: string, message: string): void  // Error

Example

dioxamine.log.i("Network", "Connecting to device socket at 127.0.0.1:8080");
dioxamine.log.e("Sync", "File transfer aborted unexpectedly");

Automatic Console Hooking

Dioxamine automatically hooks standard JavaScript console methods:

  • console.log(...) -> Forwarded to dioxamine.log.d()
  • console.info(...) -> Forwarded to dioxamine.log.i()
  • console.warn(...) -> Forwarded to dioxamine.log.w()
  • console.error(...) -> Forwarded to dioxamine.log.e()

Objects, errors, and arrays passed to console.log() are automatically serialized to JSON strings.


Inspecting Logs via ADB

You can monitor plugin runtime messages in real time using the ADB CLI from your PC:

adb logcat -s "Plugin:com.example.myplugin" "PluginJS:com.example.myplugin"

Chrome DevTools Remote Debugging

To inspect elements, view network requests, or set breakpoints using Chrome DevTools on your computer:

  1. Open Dioxamine on your phone.
  2. Navigate to Settings -> Plugins.
  3. Toggle Enable WebView Debugging on.
  4. On your PC, open Google Chrome and navigate to chrome://inspect.
  5. Under Remote Target, find your plugin WebView and click inspect.

Dynamic Theming and Material 3

Dioxamine automatically extracts the user’s dynamic Material You / Material 3 color scheme and injects CSS custom properties (variables) into every loaded plugin.


Injected CSS Custom Properties

The following CSS variables are available in the :root pseudo-class:

VariableDescription
--dioxamine-bgMain background color (maps to --dioxamine-background).
--dioxamine-fgMain text color (maps to --dioxamine-on-background).
--dioxamine-card-bgCard and surface container background.
--dioxamine-card-fgText color on surface cards.
--dioxamine-accentPrimary accent color (maps to --dioxamine-primary).
--dioxamine-dangerError and destructive action color.
--dioxamine-outlineBorder outline color.
--dioxamine-outline-variantSubtle divider and secondary border color.
--dioxamine-surface-variantSecondary surface container color.
--dioxamine-on-surface-variantSecondary muted text color.

Using Variables in CSS

body {
    background-color: var(--dioxamine-bg, #121212);
    color: var(--dioxamine-fg, #ffffff);
}

.card {
    background-color: var(--dioxamine-card-bg, #1e1e1e);
    color: var(--dioxamine-card-fg, #ffffff);
    border: 1px solid var(--dioxamine-outline-variant, #333333);
    border-radius: 12px;
}

button.primary {
    background-color: var(--dioxamine-accent, #2196f3);
    color: var(--dioxamine-on-primary, #ffffff);
}

button.danger {
    background-color: var(--dioxamine-danger, #f44336);
    color: #ffffff;
}

Dark Mode Attribute

Dioxamine sets the data-dioxamine-theme attribute on the root <html> element:

<html data-dioxamine-theme="dark">

You can target specific themes in CSS:

[data-dioxamine-theme="dark"] .custom-shadow {
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.5);
}

[data-dioxamine-theme="light"] .custom-shadow {
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
}

JavaScript Theme APIs

dioxamine.getTheme()

Queries the current theme state synchronously.

const theme = dioxamine.getTheme();
console.log("Is dark theme active?", theme.isDark);

dioxamine.onThemeChange()

Registers a listener called when the user changes the system or app theme.

dioxamine.onThemeChange(() => {
    const isDark = dioxamine.getTheme().isDark;
    console.log("Theme switched to:", isDark ? "Dark" : "Light");
    // Update charts, canvas, or WebGL shaders
});

Packaging and Distribution

Dioxamine plugins are distributed as standard ZIP archives containing the manifest and web assets.


Package Directory Structure

Before packaging, verify that all necessary files reside at the top level of your plugin folder:

com.example.myplugin/
├── plugin.json       (Required: Manifest file)
├── index.html        (Required: Entrypoint file)
├── styles.css        (Optional: Stylesheets)
├── app.js            (Optional: JavaScript scripts)
└── icon.png          (Optional: 512x512 PNG icon)

Creating the ZIP Package

Using Command Line (Linux / macOS)

cd com.example.myplugin
zip -r ../com.example.myplugin.zip *

Using PowerShell (Windows)

Compress-Archive -Path "C:\path\to\com.example.myplugin\*" -DestinationPath "C:\path\to\com.example.myplugin.zip" -Force

Important Packaging Rules

  1. No Root Wrapper Directory: Do not zip the outer folder itself. Zip the contents of the folder so that plugin.json is at the root of the ZIP archive.
  2. Naming Convention: Name the archive <plugin-id>.zip (for example, com.example.deviceinfo.zip).
  3. Asset References: Use relative paths in HTML (<link rel="stylesheet" href="styles.css">, <script src="app.js"></script>). Do not use absolute filesystem paths.

Installing Plugins in Dioxamine

  1. Transfer your .zip package to your Android device (or download it directly).
  2. Open Dioxamine and go to the ADB tab.
  3. Switch to the Plugins sub-tab and tap Install Plugin.
  4. Select your .zip archive using the system document picker.
  5. Dioxamine will validate the manifest, extract the files into its secure sandbox, and add the plugin to your installed list immediately.

Complete Plugin Examples

This chapter provides complete source code references for three typical Dioxamine plugin types:

  1. Windowed Dashboard: Single-shot shell commands and Material 3 cards.
  2. Terminal Console: Interactive PTY shell with xterm.js in full-screen mode.
  3. Live Streamer: Real-time continuous logcat stream with custom controls.

1. Device Dashboard Plugin

A standard windowed page plugin demonstrating non-interactive shellExec(), Material 3 card styling, and native UI dialogs.

plugin.json

{
  "schemaVersion": 1,
  "id": "com.example.dashboard",
  "name": "Device Dashboard",
  "description": "System specifications and quick diagnostics demo",
  "version": "1.0.0",
  "versionCode": 1,
  "author": "Dioxamine Community",
  "entry": "index.html",
  "icon": "icon.png",
  "minAppVersionCode": 1,
  "permissions": [
    "shell"
  ],
  "fullscreen": false
}

app.js

async function refreshSpecs() {
    try {
        const model = await dioxamine.shellExec("getprop ro.product.model");
        const androidVer = await dioxamine.shellExec("getprop ro.build.version.release");
        const kernel = await dioxamine.shellExec("uname -r");

        document.getElementById('val-model').textContent = model.stdout.trim() || '-';
        document.getElementById('val-version').textContent = androidVer.stdout.trim() || '-';
        document.getElementById('val-kernel').textContent = kernel.stdout.trim() || '-';
    } catch (err) {
        dioxamine.showToast("Failed to query device specs: " + err.message, "long");
    }
}

document.getElementById('refresh-btn').addEventListener('click', refreshSpecs);

2. Interactive Terminal (xterm.js)

A full-screen interactive PTY terminal connecting xterm.js to openInteractiveShell().

plugin.json

{
  "schemaVersion": 1,
  "id": "com.example.terminal",
  "name": "Terminal",
  "description": "Interactive PTY terminal using xterm.js",
  "version": "1.0.0",
  "versionCode": 1,
  "author": "Dioxamine Community",
  "entry": "index.html",
  "icon": "icon.png",
  "minAppVersionCode": 1,
  "permissions": [
    "shell"
  ],
  "fullscreen": true
}

app.js

const term = new Terminal({
    cursorBlink: true,
    fontFamily: 'monospace',
    theme: { background: '#121212', foreground: '#ffffff' }
});

term.open(document.getElementById('terminal-container'));

async function connectTerminal() {
    try {
        const session = await dioxamine.openInteractiveShell();

        // Target device stdout -> xterm.js
        session.onData((b64Chunk) => {
            const text = dioxamine.base64ToUtf8(b64Chunk);
            term.write(text);
        });

        // User input -> Target device stdin
        term.onData((data) => {
            session.write(dioxamine.utf8ToBase64(data));
        });

        session.onClose((err) => {
            term.writeln("\r\n[Stream Closed: " + (err || "OK") + "]");
        });
    } catch (err) {
        term.writeln("\r\nFailed to start shell: " + err.message);
    }
}

connectTerminal();

3. Live Logcat Streamer

A full-screen streaming log viewer featuring tag filtering, log level color coding, and throttled batch rendering.

plugin.json

{
  "schemaVersion": 1,
  "id": "com.example.logcat",
  "name": "Live Logcat",
  "description": "Real-time streaming Logcat viewer with color coding and search",
  "version": "1.0.0",
  "versionCode": 1,
  "author": "Dioxamine Community",
  "entry": "index.html",
  "icon": "icon.png",
  "minAppVersionCode": 1,
  "permissions": [
    "shell"
  ],
  "fullscreen": true
}

app.js

let session = null;
let logBuffer = '';

async function startLogcat() {
    session = await dioxamine.openInteractiveShell();

    session.onData((b64Chunk) => {
        const text = dioxamine.base64ToUtf8(b64Chunk);
        logBuffer += text;

        const lines = logBuffer.split('\n');
        logBuffer = lines.pop(); // Retain partial trailing line

        for (let i = 0; i < lines.length; i++) {
            const line = lines[i].trimEnd();
            if (line) appendLogLine(line);
        }
    });

    // Continuously follow the last 25 lines (-T 25)
    const cmd = "logcat -v time -T 25\n";
    await session.write(dioxamine.utf8ToBase64(cmd));
}

function appendLogLine(line) {
    const container = document.getElementById('log-container');
    const div = document.createElement('div');
    div.className = 'log-line';
    div.textContent = line;
    container.appendChild(div);
    container.scrollTop = container.scrollHeight;
}