moonlight-android
moonlight-android copied to clipboard
Flashing Guide Button Xbox 360 Wireless
Describe the bug Guide button on the Xbox 360 Wireless controller continues flashing (as if not connected) while actually connected and working perfectly otherwise. It seems like Moonlight might need to do something to establish permission with the OS in order to correctly access the USB device. I'm guessing so because the Steam app does seem to do that. See the workaround below for more context.
The workaround is to open the Steam app on the TV (not via Moonlight). This brings up an Android looking prompt that asks the user to allow permissions for Steam to access the USB device. Once accepting the prompt, the button stops flashing. Now we can close the Steam app and launch Moonlight normally. The Guide button remains solid and connected.
Here is the setup: Sony Bravia A80J (Google TV) Microsoft X360 Wireless USB dongle Microsoft Xbox 360 Controller
Steps to reproduce Turn on TV, turn on controller, open Moonlight.
Screenshots
Affected games All
Other Moonlight clients No.
Moonlight settings (please complete the following information)
- Have any settings been adjusted from defaults? No.
- If so, which settings have been changed? N/A
- Does the problem still occur after reverting settings back to default? Yes.
Gamepad-related issues (please complete if problem is gamepad-related)
- Do you have any gamepads connected to your host PC directly? No.
- If gamepad input is not working, does it work if you use Moonlight's on-screen controls? Input works.
- Does the problem still remain if you stream the desktop and use https://html5gamepad.com to test your gamepad? Yes.
- Instructions for streaming the desktop can be found here: https://github.com/moonlight-stream/moonlight-docs/wiki/Setup-Guide
Device details (please complete the following information)
- Android version: 10
- Device model: Sony Bravia A80J
Server PC details (please complete the following information)
- OS: Windows 11 21H2
- GeForce Experience version: 3.25.084
- Nvidia GPU driver: 511.79
- Antivirus and firewall software: Windows Defender and Windows Firewall
This is probably because the Linux kernel on your Android TV is old and lacks the logic to set the player LED indicator properly (specifically https://github.com/torvalds/linux/commit/75b7f05d2798ee3a1cc5bbdd54acd0e318a80396). As a result, it just keeps flashing.
Both Steam Link and Moonlight include USB drivers to support old Android devices without native Xbox controller support (or using an outdated kernel). Moonlight's supports wired Xbox One and Xbox 360 controllers and Steam Link's supports wired Xbox One and wired/wireless Xbox 360 controllers.
The intent of the USB driver was to handle Android devices that had missing or limited Xbox One controller support and third-party Xbox 360 wired controllers with non-standard device IDs. Since Xbox 360 wireless adapters have pretty much been universally well supported in the Linux kernel since the beginning of Moonlight's life (apart from this cosmetic issue with the player LED), there was never really a need to add a driver for them.
If someone wants to take a stab at it, I definitely would consider accepting a Xbox 360 wireless driver, assuming the change is not super intrusive. It's probably not something that will be high on my personal priority list, since all currently supported Android kernels (4.9+) contain the aforementioned patch already. I just tried my Galaxy Note 9 running the oldest actively supported Linux kernel (4.9, released in December 2016) and it set the player LED correctly right out of the box.
I see what you mean. It's scary that Sony's newest TV is running a kernel that's nearly EOL. Let's hope Sony is planning an update. For security's sake, at the very least.
I've been playing with this. I have something that seems to initialize the controller correctly.
I have these checks that can determine if it's the right kind of controller (modified from the existing driver).
private static final int XB360_IFACE_SUBCLASS = 93;
private static final int XB360_IFACE_PROTOCOL = 129; // Wireless
private static final int[] SUPPORTED_VENDORS = {
0x045e, // Microsoft
};
And I have this for setting the lights correctly.
private boolean sendLedCommand(byte command) {
byte[] commandBuffer = {
0x00,
0x00,
0x08,
(byte) (0x40 + command),
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00};
int res = connection.bulkTransfer(outEndpt, commandBuffer, commandBuffer.length, 3000);
if (res != commandBuffer.length) {
LimeLog.warning("LED set transfer failed: "+res);
return false;
}
return true;
}
@Override
protected boolean doInit() {
// Turn the LED on corresponding to our device ID
sendLedCommand((byte)(2 + (getControllerId() % 4)));
// No need to fail init if the LED command fails
return true;
}
This works. The trouble I have is where to stick this code. I initially thought to modify the existing XBOX driver, but I didn't get that to work. It seems to lock up all input, not sure why. But it does prompt for permission to use the controller and it does set the lights correctly.
Considering the buttons work already, I'm hoping there is a clean place to just check if needed and send these bytes without having a separate driver owning the controller. I want whatever is handling it already to keep handling it.
Maybe someone can point me to where the controllers are being detected, and I can play with something there? Or if you have another idea.
With 2023 TVs still releasing with Android 10, I won't be surprised if a lot of people are abandoned on this 4.19.75 kernel. It will be nice to have this little annoyance squashed.
Thanks for any help.
Pull request submitted: https://github.com/moonlight-stream/moonlight-android/pull/1157