mirror of
https://github.com/moonlight-stream/moonlight-android.git
synced 2026-10-23 08:30:32 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
36f132942f | ||
|
|
e4c251e7ee | ||
|
|
fb54bd5c78 | ||
|
|
8d4c86e113 | ||
|
|
7fafb8e0ff | ||
|
|
fbcbe09255 | ||
|
|
e336a4446a | ||
|
|
ffb35b2cdd | ||
|
|
2d0af6281c |
No files matched your search
+3
-3
@@ -5,14 +5,14 @@ apply plugin: 'com.android.application'
|
|||||||
|
|
||||||
android {
|
android {
|
||||||
compileSdkVersion 27
|
compileSdkVersion 27
|
||||||
buildToolsVersion '27.0.2'
|
buildToolsVersion '27.0.3'
|
||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
minSdkVersion 16
|
minSdkVersion 16
|
||||||
targetSdkVersion 27
|
targetSdkVersion 27
|
||||||
|
|
||||||
versionName "5.6.2"
|
versionName "5.6.4"
|
||||||
versionCode = 140
|
versionCode = 143
|
||||||
}
|
}
|
||||||
|
|
||||||
flavorDimensions "root"
|
flavorDimensions "root"
|
||||||
|
|||||||
@@ -294,6 +294,16 @@ public class Game extends Activity implements SurfaceHolder.Callback,
|
|||||||
if (prefConfig.videoFormat == PreferenceConfiguration.FORCE_H265_ON && !decoderRenderer.isHevcSupported()) {
|
if (prefConfig.videoFormat == PreferenceConfiguration.FORCE_H265_ON && !decoderRenderer.isHevcSupported()) {
|
||||||
Toast.makeText(this, "No H.265 decoder found.\nFalling back to H.264.", Toast.LENGTH_LONG).show();
|
Toast.makeText(this, "No H.265 decoder found.\nFalling back to H.264.", Toast.LENGTH_LONG).show();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int gamepadMask = ControllerHandler.getAttachedControllerMask(this);
|
||||||
|
if (!prefConfig.multiController && gamepadMask != 0) {
|
||||||
|
// If any gamepads are present in non-MC mode, set only gamepad 1.
|
||||||
|
gamepadMask = 1;
|
||||||
|
}
|
||||||
|
if (prefConfig.onscreenController) {
|
||||||
|
// If we're using OSC, always set at least gamepad 1.
|
||||||
|
gamepadMask |= 1;
|
||||||
|
}
|
||||||
|
|
||||||
StreamConfiguration config = new StreamConfiguration.Builder()
|
StreamConfiguration config = new StreamConfiguration.Builder()
|
||||||
.setResolution(prefConfig.width, prefConfig.height)
|
.setResolution(prefConfig.width, prefConfig.height)
|
||||||
@@ -302,11 +312,12 @@ public class Game extends Activity implements SurfaceHolder.Callback,
|
|||||||
.setBitrate(prefConfig.bitrate * 1000)
|
.setBitrate(prefConfig.bitrate * 1000)
|
||||||
.setEnableSops(prefConfig.enableSops)
|
.setEnableSops(prefConfig.enableSops)
|
||||||
.enableLocalAudioPlayback(prefConfig.playHostAudio)
|
.enableLocalAudioPlayback(prefConfig.playHostAudio)
|
||||||
.setMaxPacketSize(remote ? 1024 : 1292)
|
.setMaxPacketSize((remote || prefConfig.width <= 1920) ? 1024 : 1292)
|
||||||
.setRemote(remote)
|
.setRemote(remote)
|
||||||
.setHevcBitratePercentageMultiplier(75)
|
.setHevcBitratePercentageMultiplier(75)
|
||||||
.setHevcSupported(decoderRenderer.isHevcSupported())
|
.setHevcSupported(decoderRenderer.isHevcSupported())
|
||||||
.setEnableHdr(willStreamHdr)
|
.setEnableHdr(willStreamHdr)
|
||||||
|
.setAttachedGamepadMask(gamepadMask)
|
||||||
.setAudioConfiguration(prefConfig.enable51Surround ?
|
.setAudioConfiguration(prefConfig.enable51Surround ?
|
||||||
MoonBridge.AUDIO_CONFIGURATION_51_SURROUND :
|
MoonBridge.AUDIO_CONFIGURATION_51_SURROUND :
|
||||||
MoonBridge.AUDIO_CONFIGURATION_STEREO)
|
MoonBridge.AUDIO_CONFIGURATION_STEREO)
|
||||||
|
|||||||
@@ -2,6 +2,8 @@ package com.limelight.binding.input;
|
|||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.hardware.input.InputManager;
|
import android.hardware.input.InputManager;
|
||||||
|
import android.hardware.usb.UsbDevice;
|
||||||
|
import android.hardware.usb.UsbManager;
|
||||||
import android.os.SystemClock;
|
import android.os.SystemClock;
|
||||||
import android.util.SparseArray;
|
import android.util.SparseArray;
|
||||||
import android.view.InputDevice;
|
import android.view.InputDevice;
|
||||||
@@ -12,6 +14,7 @@ import android.widget.Toast;
|
|||||||
|
|
||||||
import com.limelight.LimeLog;
|
import com.limelight.LimeLog;
|
||||||
import com.limelight.binding.input.driver.UsbDriverListener;
|
import com.limelight.binding.input.driver.UsbDriverListener;
|
||||||
|
import com.limelight.binding.input.driver.UsbDriverService;
|
||||||
import com.limelight.nvstream.NvConnection;
|
import com.limelight.nvstream.NvConnection;
|
||||||
import com.limelight.nvstream.input.ControllerPacket;
|
import com.limelight.nvstream.input.ControllerPacket;
|
||||||
import com.limelight.nvstream.input.MouseButtonPacket;
|
import com.limelight.nvstream.input.MouseButtonPacket;
|
||||||
@@ -48,7 +51,7 @@ public class ControllerHandler implements InputManager.InputDeviceListener, UsbD
|
|||||||
private boolean hasGameController;
|
private boolean hasGameController;
|
||||||
|
|
||||||
private final boolean multiControllerEnabled;
|
private final boolean multiControllerEnabled;
|
||||||
private short currentControllers;
|
private short currentControllers, initialControllers;
|
||||||
|
|
||||||
public ControllerHandler(Context activityContext, NvConnection conn, GameGestures gestures, boolean multiControllerEnabled, int deadzonePercentage) {
|
public ControllerHandler(Context activityContext, NvConnection conn, GameGestures gestures, boolean multiControllerEnabled, int deadzonePercentage) {
|
||||||
this.activityContext = activityContext;
|
this.activityContext = activityContext;
|
||||||
@@ -102,6 +105,12 @@ public class ControllerHandler implements InputManager.InputDeviceListener, UsbD
|
|||||||
// consume these. Instead, let's ignore them since that's probably the
|
// consume these. Instead, let's ignore them since that's probably the
|
||||||
// most likely case.
|
// most likely case.
|
||||||
defaultContext.ignoreBack = true;
|
defaultContext.ignoreBack = true;
|
||||||
|
|
||||||
|
// Get the initially attached set of gamepads. As each gamepad receives
|
||||||
|
// its initial InputEvent, we will move these from this set onto the
|
||||||
|
// currentControllers set which will allow them to properly unplug
|
||||||
|
// if they are removed.
|
||||||
|
initialControllers = getAttachedControllerMask(activityContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static InputDevice.MotionRange getMotionRangeForJoystickAxis(InputDevice dev, int axis) {
|
private static InputDevice.MotionRange getMotionRangeForJoystickAxis(InputDevice dev, int axis) {
|
||||||
@@ -139,8 +148,47 @@ public class ControllerHandler implements InputManager.InputDeviceListener, UsbD
|
|||||||
onInputDeviceAdded(deviceId);
|
onInputDeviceAdded(deviceId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static short getAttachedControllerMask(Context context) {
|
||||||
|
int count = 0;
|
||||||
|
short mask = 0;
|
||||||
|
|
||||||
|
// Count all input devices that are gamepads
|
||||||
|
InputManager im = (InputManager) context.getSystemService(Context.INPUT_SERVICE);
|
||||||
|
for (int id : im.getInputDeviceIds()) {
|
||||||
|
InputDevice dev = im.getInputDevice(id);
|
||||||
|
if (dev == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((dev.getSources() & InputDevice.SOURCE_JOYSTICK) != 0) {
|
||||||
|
LimeLog.info("Counting InputDevice: "+dev.getName());
|
||||||
|
mask |= 1 << count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Count all USB devices that match our drivers
|
||||||
|
UsbManager usbManager = (UsbManager) context.getSystemService(Context.USB_SERVICE);
|
||||||
|
for (UsbDevice dev : usbManager.getDeviceList().values()) {
|
||||||
|
if (UsbDriverService.shouldClaimDevice(dev)) {
|
||||||
|
LimeLog.info("Counting UsbDevice: "+dev.getDeviceName());
|
||||||
|
mask |= 1 << count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LimeLog.info("Enumerated "+count+" gamepads");
|
||||||
|
return mask;
|
||||||
|
}
|
||||||
|
|
||||||
private void releaseControllerNumber(GenericControllerContext context) {
|
private void releaseControllerNumber(GenericControllerContext context) {
|
||||||
// If this device sent data as a gamepad, zero the values before removing
|
// If we reserved a controller number, remove that reservation
|
||||||
|
if (context.reservedControllerNumber) {
|
||||||
|
LimeLog.info("Controller number "+context.controllerNumber+" is now available");
|
||||||
|
currentControllers &= ~(1 << context.controllerNumber);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If this device sent data as a gamepad, zero the values before removing.
|
||||||
|
// We must do this after clearing the currentControllers entry so this
|
||||||
|
// causes the device to be removed on the server PC.
|
||||||
if (context.assignedControllerNumber) {
|
if (context.assignedControllerNumber) {
|
||||||
conn.sendControllerInput(context.controllerNumber, getActiveControllerMask(),
|
conn.sendControllerInput(context.controllerNumber, getActiveControllerMask(),
|
||||||
(short) 0,
|
(short) 0,
|
||||||
@@ -148,12 +196,6 @@ public class ControllerHandler implements InputManager.InputDeviceListener, UsbD
|
|||||||
(short) 0, (short) 0,
|
(short) 0, (short) 0,
|
||||||
(short) 0, (short) 0);
|
(short) 0, (short) 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we reserved a controller number, remove that reservation
|
|
||||||
if (context.reservedControllerNumber) {
|
|
||||||
LimeLog.info("Controller number "+context.controllerNumber+" is now available");
|
|
||||||
currentControllers &= ~(1 << context.controllerNumber);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Called before sending input but after we've determined that this
|
// Called before sending input but after we've determined that this
|
||||||
@@ -181,6 +223,10 @@ public class ControllerHandler implements InputManager.InputDeviceListener, UsbD
|
|||||||
if ((currentControllers & (1 << i)) == 0) {
|
if ((currentControllers & (1 << i)) == 0) {
|
||||||
// Found an unused controller value
|
// Found an unused controller value
|
||||||
currentControllers |= (1 << i);
|
currentControllers |= (1 << i);
|
||||||
|
|
||||||
|
// Take this value out of the initial gamepad set
|
||||||
|
initialControllers &= ~(1 << i);
|
||||||
|
|
||||||
context.controllerNumber = i;
|
context.controllerNumber = i;
|
||||||
context.reservedControllerNumber = true;
|
context.reservedControllerNumber = true;
|
||||||
break;
|
break;
|
||||||
@@ -201,6 +247,10 @@ public class ControllerHandler implements InputManager.InputDeviceListener, UsbD
|
|||||||
if ((currentControllers & (1 << i)) == 0) {
|
if ((currentControllers & (1 << i)) == 0) {
|
||||||
// Found an unused controller value
|
// Found an unused controller value
|
||||||
currentControllers |= (1 << i);
|
currentControllers |= (1 << i);
|
||||||
|
|
||||||
|
// Take this value out of the initial gamepad set
|
||||||
|
initialControllers &= ~(1 << i);
|
||||||
|
|
||||||
context.controllerNumber = i;
|
context.controllerNumber = i;
|
||||||
context.reservedControllerNumber = true;
|
context.reservedControllerNumber = true;
|
||||||
break;
|
break;
|
||||||
@@ -473,7 +523,7 @@ public class ControllerHandler implements InputManager.InputDeviceListener, UsbD
|
|||||||
|
|
||||||
private short getActiveControllerMask() {
|
private short getActiveControllerMask() {
|
||||||
if (multiControllerEnabled) {
|
if (multiControllerEnabled) {
|
||||||
return currentControllers;
|
return (short)(currentControllers | initialControllers);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Only Player 1 is active with multi-controller disabled
|
// Only Player 1 is active with multi-controller disabled
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package com.limelight.binding.input.capture;
|
|||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
|
|
||||||
import com.limelight.LimeLog;
|
import com.limelight.LimeLog;
|
||||||
|
import com.limelight.LimelightBuildProps;
|
||||||
import com.limelight.R;
|
import com.limelight.R;
|
||||||
import com.limelight.binding.input.evdev.EvdevCaptureProviderShim;
|
import com.limelight.binding.input.evdev.EvdevCaptureProviderShim;
|
||||||
import com.limelight.binding.input.evdev.EvdevListener;
|
import com.limelight.binding.input.evdev.EvdevListener;
|
||||||
@@ -13,7 +14,9 @@ public class InputCaptureManager {
|
|||||||
LimeLog.info("Using Android O+ native mouse capture");
|
LimeLog.info("Using Android O+ native mouse capture");
|
||||||
return new AndroidNativePointerCaptureProvider(activity.findViewById(R.id.surfaceView));
|
return new AndroidNativePointerCaptureProvider(activity.findViewById(R.id.surfaceView));
|
||||||
}
|
}
|
||||||
else if (ShieldCaptureProvider.isCaptureProviderSupported()) {
|
// LineageOS implemented broken NVIDIA capture extensions, so avoid using them on root builds.
|
||||||
|
// See https://github.com/LineageOS/android_frameworks_base/commit/d304f478a023430f4712dbdc3ee69d9ad02cebd3
|
||||||
|
else if (!LimelightBuildProps.ROOT_BUILD && ShieldCaptureProvider.isCaptureProviderSupported()) {
|
||||||
LimeLog.info("Using NVIDIA mouse capture extension");
|
LimeLog.info("Using NVIDIA mouse capture extension");
|
||||||
return new ShieldCaptureProvider(activity);
|
return new ShieldCaptureProvider(activity);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -157,7 +157,7 @@ public class UsbDriverService extends Service implements UsbDriverListener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isRecognizedInputDevice(UsbDevice device) {
|
private static boolean isRecognizedInputDevice(UsbDevice device) {
|
||||||
// On KitKat and later, we can determine if this VID and PID combo
|
// On KitKat and later, we can determine if this VID and PID combo
|
||||||
// matches an existing input device and defer to the built-in controller
|
// matches an existing input device and defer to the built-in controller
|
||||||
// support in that case. Prior to KitKat, we'll always return true to be safe.
|
// support in that case. Prior to KitKat, we'll always return true to be safe.
|
||||||
@@ -182,7 +182,7 @@ public class UsbDriverService extends Service implements UsbDriverListener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean shouldClaimDevice(UsbDevice device) {
|
public static boolean shouldClaimDevice(UsbDevice device) {
|
||||||
// We always bind to XB1 controllers but only bind to XB360 controllers
|
// We always bind to XB1 controllers but only bind to XB360 controllers
|
||||||
// if we know the kernel isn't already driving this device.
|
// if we know the kernel isn't already driving this device.
|
||||||
return XboxOneController.canClaimDevice(device) ||
|
return XboxOneController.canClaimDevice(device) ||
|
||||||
|
|||||||
@@ -134,7 +134,7 @@ public class ComputerManagerService extends Service {
|
|||||||
public void run() {
|
public void run() {
|
||||||
|
|
||||||
int offlineCount = 0;
|
int offlineCount = 0;
|
||||||
while (!isInterrupted() && pollingActive) {
|
while (!isInterrupted() && pollingActive && tuple.thread == this) {
|
||||||
try {
|
try {
|
||||||
// Only allow one request to the machine at a time
|
// Only allow one request to the machine at a time
|
||||||
synchronized (tuple.networkLock) {
|
synchronized (tuple.networkLock) {
|
||||||
@@ -392,6 +392,7 @@ public class ComputerManagerService extends Service {
|
|||||||
if (tuple.thread != null) {
|
if (tuple.thread != null) {
|
||||||
// Interrupt the thread on this entry
|
// Interrupt the thread on this entry
|
||||||
tuple.thread.interrupt();
|
tuple.thread.interrupt();
|
||||||
|
tuple.thread = null;
|
||||||
}
|
}
|
||||||
pollingTuples.remove(tuple);
|
pollingTuples.remove(tuple);
|
||||||
break;
|
break;
|
||||||
@@ -840,6 +841,7 @@ public class ComputerManagerService extends Service {
|
|||||||
} while (waitPollingDelay());
|
} while (waitPollingDelay());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
thread.setName("App list polling thread for " + computer.localAddress);
|
||||||
thread.start();
|
thread.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,8 +2,6 @@
|
|||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
|
||||||
<!-- Non-root application name -->
|
<!-- Non-root application name -->
|
||||||
<!-- No need to extract libraries for the non-root version -->
|
<!-- FIXME: We should set extractNativeLibs=false but this breaks installation on the Fire TV 3 -->
|
||||||
<application
|
<application android:label="Moonlight" />
|
||||||
android:label="Moonlight"
|
|
||||||
android:extractNativeLibs="false" />
|
|
||||||
</manifest>
|
</manifest>
|
||||||
+1
-1
Submodule moonlight-common updated: bfd9663e92...52e09a1e69.
Reference in new issue
Block a user