dsh-inapp-plugin: Running Android Emulator on DSH Pages

Introduction

When developing games in DSH, the verification phase usually requires leaving the current workflow: opening a third-party emulator (such as MEmu, LDPlayer, BlueStacks, etc.), installing Android SDK tools, and switching between windows. These resident emulators occupy GB-level storage and a large chunk of memory, consuming resources even when not testing; another approach is manually adb screencap to export the screen back to view it, which has high latency and tedious operations.

The lordgrimtaken/dsh-inapp-plugin (Game Lab) introduced below addresses this issue within the page: it calls the Android SDK emulator tools already present on the machine, starts a headless AVD on demand, installs the game, plays it within the page, and automatically shuts down after becoming idle.

What is this

  • Plugin Name: dsh-inapp-plugin (Page-in name: Game Lab)
  • Maintainer: LordGrimTaken
  • Category: Client
  • Version: v1.2 (package.json is 1.2.0)
  • License: MIT

One-sentence positioning: A DSH plugin (host + Web UI halves) that transforms a standard Android SDK emulator into an in-page test bench, serving the loop of “modifying games, building, and viewing real-device effects.” It does not download or install any extra emulators or fetch system images; when there is no x86_64 image on the machine, it only reports the missing image, not downloading it on behalf of the user.

The screen is obtained via adb exec-out screenrecord ... - as an H.264 stream, which the page decodes and renders on a canvas using WebCodecs; when the browser does not support WebCodecs, it automatically falls back to the PNG multipart stream of adb exec-out screencap -p. Clicks, swipes, keyboard, and controller inputs are all sent to the emulator via adb.

Core Features

On-demand headless AVD. When the configured AVD (default name gamelab) does not exist, it is automatically created based on the installed x86_64 system image on the machine. Specifications are 720x1280, max 2 vCPU, using the host GPU, without a window or snapshots. The offline screen lists all installed AVDs (/status.avds), allowing selection before clicking Start.

Smooth real-time video. H.264 is encoded by the emulator and decoded and rendered by WebCodecs on the page; actual testing shows approximately 19 fps when screen changes occur. When WebCodecs is unavailable, it automatically falls back to the PNG multipart stream (approximately 0.7-1.6 fps). The toolbar provides a Smooth/Compat toggle.

Complete input. Supports click, drag/swipe, Back/Home/Recents, screen rotation, and hardware keys; the Keyboard panel can input ASCII text and Enter/Space/Backspace/Esc; the Pad panel provides a D-pad, A/B, Start, catering to games requiring button input.

Game Library and Build & play. The plugin scans the directory configured in gameRoots, groups APKs by app name (newest version first, old versions folded), remembers the last search criteria, and lists Gradle/Capacitor projects. Play directly installs and launches the APK. Build & play first detects the project type: pure Gradle runs gradlew assembleDebug; Capacitor runs npm run android:apk, or npm run build + npx cap sync android + Gradle. After completion, the latest APK is installed and launched, and /status returns the current phase.

Low idle usage. PNG/H.264 loops pause when no one is watching; the emulator stops after 5 minutes of idle (configurable), and a running build is not interrupted by the idle timer. It keeps the screen awake during operation to avoid screen lock freezing the game.

Diagnostics. The page displays real-time fps/RAM/CPU, supports logcat tail, one-click screenshot, and the status API.

Installation & Enablement

The installation command comes from the original README. Note that plugin_manager is a DSH agent tool, not a shell command:

# 让 DSH 智能体把这个本地文件夹安装为 bundle。
# plugin_manager 是 DSH 智能体工具,不是 shell 命令。
plugin_manager install_bundle target: <克隆到本地的绝对路径>

The agent tool links the folder into the profile, adds it to bundle selection and activates it immediately. If you wish to configure the profile manually, refer to docs/INSTALL.md in the repository.

Enablement steps:

  1. Reload the Harness page to load the client part.
  2. Click the Game Lab handle icon in the left sidebar.
  3. Click Start emulator; the cold boot takes about 40-60 seconds.
  4. Point gameRoots to your game directory, click Play (or Build & play), and interact via the toolbar.

System requirements: DSH with Web UI, Android SDK (ANDROID_HOME or ANDROID_SDK_ROOT), and an installed x86_64 system image; Build & play also requires JDK, and Capacitor projects require Node/npm. Windows is a tested platform, though the host code has POSIX branches that have not yet been verified on macOS/Linux.

Configuration

Configuration is written in the profile’s cordis.patch.yml, modify the game-lab line, or override bundle defaults. Adjustable fields include gameRoots, avdName, idleMinutes, ramMb, cores, gpuMode, maxFps. The bundle’s own example is:

# profile 中 cordis.patch.yml 的 game-lab 行
gameRoots: [C:\Games]

Please change gameRoots to the directory actually storing APKs or projects. See docs/CONFIGURATION.md in the repository for full field descriptions.

Typical Usage: Running Build & play Once

The following flow comes from the README’s Quick start and actual data:

  1. Point gameRoots to the directory containing the Capacitor game project.
  2. Click Start emulator and wait for the cold boot to complete (dev machine tested 36-62 seconds to interactive).
  3. Click Build & play. After the plugin detects the Capacitor project, it executes npm run build, npx cap sync android, Gradle packaging in sequence, and then installs the latest APK and launches it. Dev machine testing showed a total of 71.4 seconds from emulator close to completion of this step.
  4. During operation, use the Keyboard or Pad panel to operate the game, and use the screenshot button to save the current screen. Dev machine testing showed that installing and launching a 9.6 MB APK took 3.7 seconds, click operation round-trip latency was about 0.7 seconds, and the emulator running consumed about 3.1-3.7 GB RAM and about 2.1-2.4 cores CPU.
  5. After stopping viewing for 5 minutes, the idle stop triggers and memory is returned to the system.

See docs/VERIFICATION.md in the repository for more complete findings and unverified items.

Applicability & Notes

Suitable for users doing game development in DSH who want to see screen interaction immediately after building, but do not want to maintain resident third-party emulators. It is not suitable for multi-instance parallel testing or games with high frame rate requirements: only one emulator and one viewer can run at a time; smooth frame rate follows screen changes, static menus might only be a few frames, and fast-moving screens are around 10-20 fps.

A few notes:

  • The emulator uses about 3.5 GB of memory when running (Android 14 image plus QEMU overhead). The plugin only defers this cost until it is needed; it does not reduce per-instance cost; to reduce usage, you should switch to a lighter system image or AVD.
  • The plugin runs with the permissions of the current DSH process; check the source code and license (MIT) before installing.
  • Input of non-ASCII text requires installing ADBKeyboard in the AVD first; otherwise, only ASCII can be input.
  • The page must remain open during operation, otherwise the video stream pauses; the emulator stops after 5 minutes of idle.

Conclusion

The value of Game Lab lies in keeping “Build - Real device verification” inside the DSH page, while avoiding the storage and memory overhead of resident emulators. It only drives the local Android SDK tools and does not perform any emulator or image downloading.

  • Directory: https://www.skillhub.cn/plugins/LordGrimTaken/dsh-inapp-plugin
  • GitHub: https://github.com/LordGrimTaken/dsh-inapp-plugin
羽毛球分组比赛记分
小程序二维码

欢迎使用《羽毛球分组比赛记分》微信小程序

Xiaoye