Releases: BoredNewCoder/ds3-charger-app
Release list
v1.4.4 - Report-descriptor auth check, multi-controller Bluetooth fix, charge-retry stale-device fix
Three real changes since v1.4.3:
Second authenticity signal (report descriptor): Check Authenticity now also reads the controller's raw USB HID Report Descriptor (read-only) and byte-compares it against the genuine SIXAXIS/DS3's known 148-byte descriptor, sourced from a real USBPcap capture. Combines with the existing ADC-quantization check into one composite verdict. Deliberately does not use MAC or VID/PID as signals — both proven unreliable (MAC is a rewritable pairing address, not a serial; real clones spoof VID/PID exactly).
Multi-controller Bluetooth fix: Bluetooth battery tracking used to skip entirely whenever any USB controller was tracked, which silently dropped a genuinely second, wireless DS3 in a multi-controller setup. Now uses count-based suppression so a real second controller gets tracked while the wired-controller Bluetooth-ghost-reconnect case is still correctly ignored.
Charge-retry stale-device fix: a DS3 could plug in and then silently, permanently fail to charge — root-caused via live logcat to UsbManager.openDevice() throwing IllegalArgumentException: device ... does not exist or is restricted on every retry, because the retry path reused a stale UsbDevice object across a kernel re-enumeration race (churn correlated with an NVIDIA system app also claiming the same USB interface on every attach). Retries now re-resolve the live device instead of trusting the stale reference, and every previously-silent failure path in that chain now logs.
See README for full technical detail on all three.
v1.4.3 - Charging fix for controller plugged in while off
Fix: DS3 plugged in while off never actually charged
Real cause: when this app is the registered default handler for the DS3's USB device filter, Android delivers the attach event by launching MainActivity directly with the device in the intent — it does not also send a general broadcast, so the service's own registered USB receiver never saw a live attach event through that path. MainActivity was discarding that intent's device info instead of forwarding it, so a controller plugged in while the service wasn't already tracking it (any fresh attach, on or off) never triggered the charge-command handshake.
Live-confirmed: real operational-mode handshake now completes within ~1s of plugging in a powered-off DS3; app shows "Charging..." within seconds.
See README for the full writeup.
v1.4.2 — README update
Docs-only release — README now documents the v1.4.1 polling crash-safety fix (live-tested against a real DS3 across multiple poll cycles, no regression). No code changes since v1.4.1.
v1.4.1 — polling crash-safety fix
Real bug fix: none of the USB control-transfer calls (battery poll, authenticity check, charge command, rumble test, host pairing) were wrapped in try/catch, all running on one shared background thread. An uncaught exception there is fatal to the whole app by default, and even in a survived case the poll loop would never reach its own reschedule call — one bad controller could silently stop battery polling forever for every tracked controller. Fixed with safe wrappers at every background-thread post site and a guaranteed reschedule in a finally block.
v1.4.0 - Honest charging display
Fixes a misleading battery-percentage display: the app previously showed a hardcoded 100% while a controller was merely Charging (not yet Full), because the DS3's status byte only distinguishes Charging vs Full, no live percentage. Now shows "Charging..." with no number while actively charging, and only shows a real percentage when genuinely Full or running on battery unplugged.
This is a firmware-level limitation (confirmed against the Linux kernel hid-sony driver and DsHidMini's driver struct) - not fixable by better parsing or root access.
See README for the full technical explanation.
v1.3.0 - Charging fix, rumble test, per-device cards
What's new
Real bug fix - the app's actual purpose: found and fixed a bug that likely meant this app was never fully charging DS3 controllers since the project started. The USB wake handshake was missing a required second step (GET_REPORT feature report 0xF5) that the real Linux kernel driver always sends - without it, the controller could enumerate and report a plausible-looking battery status while charging may never have actually been engaging.
New per-device UI: the main screen now shows a card per connected controller (previously one shared status blob) - each with its own action buttons instead of one screen-wide control.
New: Check Authenticity - samples the analog stick/button ADC resolution while you move them, since genuine Sony hardware uses a real ADC and cheap clones commonly use a coarser one that produces visibly stepped values instead of smooth ones. Byte offsets verified against a real driver's source (DsHidMini).
New: Test Rumble - fires both motors in an alternating 1s pattern to confirm they both work.
New: Pair to Host... - writes the controller's stored Bluetooth "master" address via the same USB mechanism a real PS3 or SixaxisPairTool uses (DS3 pairing is USB-write-driven, not a self-contained discoverable Bluetooth mode). You type in the target host's MAC address each time - nothing device-specific is hardcoded.
Grab app-debug.apk below and sideload with adb install.
v1.2.0 - Charge-complete alerts
What's new
- Charge-complete alert: pops a real alert notification the moment a controller finishes charging (Charging → Full), separate from the silent ongoing status notification. Toggle in Settings, on by default.
- Fires independently per controller if more than one DS3 is plugged in.
- README note added on why the alert might not visibly show on some Android TV launchers (a launcher-side limitation, not this app's).
Grab ds3-charger.apk below and sideload with adb install.
v1.1.0
Adds a settings screen: adjustable battery-poll interval (1/5/15/30 min) and a toggle for the full-charge LED indicator.
v1.0.0
Initial release: charging fix + live battery %, foreground service with persistent notification, one-shot full-charge LED, multi-controller support.