mirror of
https://github.com/moonlight-stream/moonlight-android.git
synced 2026-06-17 22:31:35 +00:00
Set Lights on XBOX360 Wireless Controllers for New Android/Google TVs Through 2023 - Fixes: #1061 (#1157)
This commit is contained in:
@@ -20,6 +20,7 @@ import com.limelight.LimeLog;
|
|||||||
import com.limelight.R;
|
import com.limelight.R;
|
||||||
import com.limelight.preferences.PreferenceConfiguration;
|
import com.limelight.preferences.PreferenceConfiguration;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
public class UsbDriverService extends Service implements UsbDriverListener {
|
public class UsbDriverService extends Service implements UsbDriverListener {
|
||||||
@@ -183,6 +184,9 @@ public class UsbDriverService extends Service implements UsbDriverListener {
|
|||||||
else if (Xbox360Controller.canClaimDevice(device)) {
|
else if (Xbox360Controller.canClaimDevice(device)) {
|
||||||
controller = new Xbox360Controller(device, connection, nextDeviceId++, this);
|
controller = new Xbox360Controller(device, connection, nextDeviceId++, this);
|
||||||
}
|
}
|
||||||
|
else if (Xbox360WirelessController.canClaimDevice(device)) {
|
||||||
|
controller = new Xbox360WirelessController(device, connection, nextDeviceId++, this);
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
// Unreachable
|
// Unreachable
|
||||||
return;
|
return;
|
||||||
@@ -248,9 +252,32 @@ public class UsbDriverService extends Service implements UsbDriverListener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean kernelSupportsXbox360W() {
|
||||||
|
File systemDir = new File("/sys/class/leds");
|
||||||
|
File[] files = systemDir.listFiles();
|
||||||
|
if (files != null) {
|
||||||
|
for (File f : files) {
|
||||||
|
if (f.getName().equals("xpad0") ||
|
||||||
|
f.getName().equals("xpad1") ||
|
||||||
|
f.getName().equals("xpad2") ||
|
||||||
|
f.getName().equals("xpad3") ||
|
||||||
|
f.getName().equals("xpad4") ||
|
||||||
|
f.getName().equals("xpad5") ||
|
||||||
|
f.getName().equals("xpad6") ||
|
||||||
|
f.getName().equals("xpad7") ||
|
||||||
|
f.getName().equals("xpad8") ||
|
||||||
|
f.getName().equals("xpad9")) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public static boolean shouldClaimDevice(UsbDevice device, boolean claimAllAvailable) {
|
public static boolean shouldClaimDevice(UsbDevice device, boolean claimAllAvailable) {
|
||||||
return ((!kernelSupportsXboxOne() || !isRecognizedInputDevice(device) || claimAllAvailable) && XboxOneController.canClaimDevice(device)) ||
|
return ((!kernelSupportsXboxOne() || !isRecognizedInputDevice(device) || claimAllAvailable) && XboxOneController.canClaimDevice(device)) ||
|
||||||
((!isRecognizedInputDevice(device) || claimAllAvailable) && Xbox360Controller.canClaimDevice(device));
|
((!isRecognizedInputDevice(device) || claimAllAvailable) && Xbox360Controller.canClaimDevice(device)) ||
|
||||||
|
((!kernelSupportsXbox360W() || !isRecognizedInputDevice(device) || claimAllAvailable) && Xbox360WirelessController.canClaimDevice(device));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void start() {
|
private void start() {
|
||||||
|
|||||||
@@ -0,0 +1,82 @@
|
|||||||
|
package com.limelight.binding.input.driver;
|
||||||
|
|
||||||
|
import android.hardware.usb.UsbConstants;
|
||||||
|
import android.hardware.usb.UsbDevice;
|
||||||
|
import android.hardware.usb.UsbDeviceConnection;
|
||||||
|
|
||||||
|
import com.limelight.LimeLog;
|
||||||
|
import com.limelight.nvstream.input.ControllerPacket;
|
||||||
|
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
|
public class Xbox360WirelessController extends AbstractXboxController {
|
||||||
|
private static final int XB360W_IFACE_SUBCLASS = 93;
|
||||||
|
private static final int XB360W_IFACE_PROTOCOL = 129; // Wireless only
|
||||||
|
|
||||||
|
private static final int[] SUPPORTED_VENDORS = {
|
||||||
|
0x045e, // Microsoft
|
||||||
|
};
|
||||||
|
|
||||||
|
public static boolean canClaimDevice(UsbDevice device) {
|
||||||
|
for (int supportedVid : SUPPORTED_VENDORS) {
|
||||||
|
if (device.getVendorId() == supportedVid &&
|
||||||
|
device.getInterfaceCount() >= 1 &&
|
||||||
|
device.getInterface(0).getInterfaceClass() == UsbConstants.USB_CLASS_VENDOR_SPEC &&
|
||||||
|
device.getInterface(0).getInterfaceSubclass() == XB360W_IFACE_SUBCLASS &&
|
||||||
|
device.getInterface(0).getInterfaceProtocol() == XB360W_IFACE_PROTOCOL) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Xbox360WirelessController(UsbDevice device, UsbDeviceConnection connection, int deviceId, UsbDriverListener listener) {
|
||||||
|
super(device, connection, deviceId, listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean handleRead(ByteBuffer buffer) {
|
||||||
|
// Unreachable
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
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)));
|
||||||
|
|
||||||
|
// Close the interface and return false to give control back to the kernel.
|
||||||
|
connection.releaseInterface(device.getInterface(0));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void rumble(short lowFreqMotor, short highFreqMotor) {
|
||||||
|
// Unreachable.
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user