Skip to content

Droidwire 1.3.0

Latest

Choose a tag to compare

@ajithonmain ajithonmain released this 07 Oct 07:59
· 15 commits to main since this release

Superseded by Droidwire 1.4.0 (beta prerelease). 1.3.0 shipped without adb and its bundled libraries required macOS 26; 1.4.0 is self-contained (adb included) and supports USB and Wi-Fi. Because 1.4.0 is marked a prerelease, GitHub still lists 1.3.0 as "Latest" and the in-app update check will not announce 1.4.0; download it from the link above. This release and its files are kept unchanged for history.


First open-source release (MIT). Public release builds no longer bundle adb; install it with brew install android-platform-tools for USB and Wi-Fi modes. Updates are announced from this repository's GitHub Releases.

Removed

  • First-launch email registration and everything behind it: the sign-up screen, the beta:* IPC channels, the Firestore requests, the startup retry, the embedded Firebase configuration, and the remote "in-app messages" feature. The app now opens straight into the normal UI and collects no personal information. Update information comes from GitHub releases only.
  • The app no longer reads or writes beta-signup.json. A file left by an earlier beta build stays where it is (~/Library/Application Support/@droidwire/desktop/) and can be deleted by the user.
  • Unused code and configuration: the android workspace entry and script, electron-updater and path-browserify dependencies, a stale vite.config.ts.

Fixed

  • Folder .zip downloads put remote folder names into a shell command without quoting; names with spaces, quotes or shell metacharacters could break the command or run unintended commands on the phone. Names are now quoted, each operation uses its own temporary archive, and the archive and local scratch files are removed on failure and cancellation. Phones without an on-device zip now fall back to pulling the tree and zipping on the Mac.
  • Text previews never displayed: the renderer expected a file:// path while the main process returned a data URL. Previews now use a typed PreviewResult (images/audio as data URLs, text as decoded text, first 64 KiB).
  • MTP cut/paste and drag-to-move only renamed the object instead of moving it between folders. Moves now use MTP MoveObject, with name-change and replace handled safely and a clear message when the phone cannot do it.
  • Uploads could hang forever: a failed, cancelled or dismissed upload left its completion promise unresolved, stalling batches (including "move after upload"). Every upload now settles.
  • Queued work could run against the wrong phone after switching device or connection mode. Device and transport are captured when work is queued and carried through execution, progress polling and cancellation; transports no longer keep a hidden "current device".
  • Edit sessions, previews and video thumbnails could collide when two phones expose the same path; they are now keyed by device identity (previews use a private temp directory per request).
  • Update check treated any different version as newer. Versions are now compared as semantic versions; an older or equal release never prompts. The product version is read from one place and is the same in development and packaged builds (About and update messages previously showed Electron's version in dev).
  • MTP: a transfer whose upload failed could previously delete the existing destination file first; uploads that replace now complete before the old file is removed. Concurrent operations on different MTP devices can no longer interleave on the single libmtp session.
  • A video-thumbnail request served the active device's file regardless of which device the request was for.
  • A failed or cancelled download no longer leaves a partial file or destroys an existing file of the same name: downloads go to a temporary name and are renamed on success.
  • Audio previews were blocked by the page's Content Security Policy.

Security

  • All IPC arguments are validated; persistence keys come from an allowlist (the key used to build file names could previously traverse directories); delete-local-file only deletes files that were just uploaded by the user's "move" choice; read-local-file removed; APK install requires an .apk file.
  • Download, preview, drag and edit file names are reduced to a single safe path component; destination paths are checked to stay inside their directory.
  • Renderer cannot navigate away from the app page or open windows; web permission requests are denied; external links are limited to https://github.com; a strict Content-Security-Policy replaces the stale tethering-era one.
  • Video-thumbnail loopback server: unguessable per-stream tokens bound to one device and path, Host header check, GET only, range validation, connections closed on quit; ffmpeg is restricted to http,tcp input.
  • Executable file types (.command, .app, .sh, ...) are not opened automatically by Open & Edit.
  • MTP worker supervision: startup timeout, failure on exit-before-ready, and a late exit from a killed worker can no longer reject calls of its replacement; the worker exits with its parent.
  • Deleting or moving a storage root is refused; adb/ffmpeg lookup order is explicit; child processes (transfers, range server, QR pairing, MTP worker) are shut down on quit; messages to closed windows no longer throw.

Changed

  • Main process split into modules (ipc/, transports, lib/) with one implementation each of device listing, ls parsing, MIME mapping and shell quoting (previously duplicated across files).
  • Update checks are configurable (Droidwire menu > Check for Updates Automatically) and documented. DROIDWIRE_OFFLINE=1 disables them for tests.
  • Wireless ADB inputs are validated; the folder adb:find escapes glob characters.
  • Build: node scripts/bootstrap.mjs finds libmtp and installs reliably (a plain npm ci failed on a clean Mac when libmtp was not on the linker path); rebuild:mtp detects the libmtp prefix instead of assuming /opt/homebrew; bundle-native.sh verifies relocatability and architecture; the packaged app.asar shrank from about 1.5 GB to under 1 MB by shipping only compiled output.
  • Playwright smoke driver derives paths from its own location and runs against a throwaway profile.

Added

  • MIT LICENSE and license fields in the package manifests.
  • Unit tests (npm test), npm run typecheck, npm run verify, GitHub Actions CI, issue and pull-request templates, CONTRIBUTING, SECURITY, hardware checklist, licensing inventory.

Install

Unsigned build: after dragging to Applications run xattr -dr com.apple.quarantine /Applications/Droidwire.app. For USB and Wi-Fi modes install adb: brew install android-platform-tools (MTP mode does not need it). Apple Silicon only; Intel is untested.

Not tested on real phones in this release (see docs/HARDWARE-CHECKLIST.md). Licensed MIT.