Compare commits
9 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| deb78e1c64 | |||
| 9aec6b1d31 | |||
| 97702b8861 | |||
| 832e7197c5 | |||
| 26b992726c | |||
| 1cb3588841 | |||
| b461d546d6 | |||
| b7810d6eb6 | |||
| 6fb3a8e57d |
+5
-5
@@ -1,15 +1,15 @@
|
||||
apply plugin: 'com.android.application'
|
||||
|
||||
android {
|
||||
buildToolsVersion '28.0.3'
|
||||
compileSdkVersion 28
|
||||
buildToolsVersion '29.0.0'
|
||||
compileSdkVersion 29
|
||||
|
||||
defaultConfig {
|
||||
minSdkVersion 16
|
||||
targetSdkVersion 28
|
||||
targetSdkVersion 29
|
||||
|
||||
versionName "7.3.1"
|
||||
versionCode = 194
|
||||
versionName "7.4"
|
||||
versionCode = 195
|
||||
}
|
||||
|
||||
flavorDimensions "root"
|
||||
|
||||
@@ -119,7 +119,8 @@ public class Game extends Activity implements SurfaceHolder.Callback,
|
||||
private MediaCodecDecoderRenderer decoderRenderer;
|
||||
private boolean reportedCrash;
|
||||
|
||||
private WifiManager.WifiLock wifiLock;
|
||||
private WifiManager.WifiLock highPerfWifiLock;
|
||||
private WifiManager.WifiLock lowLatencyWifiLock;
|
||||
|
||||
private boolean connectedToUsbDriverService = false;
|
||||
private ServiceConnection usbDriverServiceConnection = new ServiceConnection() {
|
||||
@@ -228,9 +229,15 @@ public class Game extends Activity implements SurfaceHolder.Callback,
|
||||
|
||||
// Make sure Wi-Fi is fully powered up
|
||||
WifiManager wifiMgr = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
|
||||
wifiLock = wifiMgr.createWifiLock(WifiManager.WIFI_MODE_FULL_HIGH_PERF, "Limelight");
|
||||
wifiLock.setReferenceCounted(false);
|
||||
wifiLock.acquire();
|
||||
highPerfWifiLock = wifiMgr.createWifiLock(WifiManager.WIFI_MODE_FULL_HIGH_PERF, "Moonlight High Perf Lock");
|
||||
highPerfWifiLock.setReferenceCounted(false);
|
||||
highPerfWifiLock.acquire();
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
||||
lowLatencyWifiLock = wifiMgr.createWifiLock(WifiManager.WIFI_MODE_FULL_LOW_LATENCY, "Moonlight Low Latency Lock");
|
||||
lowLatencyWifiLock.setReferenceCounted(false);
|
||||
lowLatencyWifiLock.acquire();
|
||||
}
|
||||
|
||||
String host = Game.this.getIntent().getStringExtra(EXTRA_HOST);
|
||||
String appName = Game.this.getIntent().getStringExtra(EXTRA_APP_NAME);
|
||||
@@ -510,8 +517,17 @@ public class Game extends Activity implements SurfaceHolder.Callback,
|
||||
// Capture is lost when focus is lost, so it must be requested again
|
||||
// when focus is regained.
|
||||
if (inputCaptureProvider.isCapturingEnabled() && hasFocus) {
|
||||
// Recapture the pointer if focus was regained
|
||||
streamView.requestPointerCapture();
|
||||
// Recapture the pointer if focus was regained. On Android Q,
|
||||
// we have to delay a bit before requesting capture because otherwise
|
||||
// we'll hit the "requestPointerCapture called for a window that has no focus"
|
||||
// error and it will not actually capture the cursor.
|
||||
Handler h = new Handler();
|
||||
h.postDelayed(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
streamView.requestPointerCapture();
|
||||
}
|
||||
}, 500);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -702,7 +718,12 @@ public class Game extends Activity implements SurfaceHolder.Callback,
|
||||
inputManager.unregisterInputDeviceListener(controllerHandler);
|
||||
}
|
||||
|
||||
wifiLock.release();
|
||||
if (lowLatencyWifiLock != null) {
|
||||
lowLatencyWifiLock.release();
|
||||
}
|
||||
if (highPerfWifiLock != null) {
|
||||
highPerfWifiLock.release();
|
||||
}
|
||||
|
||||
if (connectedToUsbDriverService) {
|
||||
// Unbind from the discovery service
|
||||
@@ -1393,7 +1414,7 @@ public class Game extends Activity implements SurfaceHolder.Callback,
|
||||
public void run() {
|
||||
inputCaptureProvider.enableCapture();
|
||||
}
|
||||
}, 1000);
|
||||
}, 500);
|
||||
|
||||
// Keep the display on
|
||||
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
|
||||
|
||||
@@ -335,17 +335,23 @@ public class ControllerHandler implements InputManager.InputDeviceListener, UsbD
|
||||
}
|
||||
|
||||
private static boolean isExternal(InputDevice dev) {
|
||||
try {
|
||||
// Landroid/view/InputDevice;->isExternal()Z is on the light graylist in Android P
|
||||
return (Boolean)dev.getClass().getMethod("isExternal").invoke(dev);
|
||||
} catch (NoSuchMethodException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
} catch (InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
} catch (ClassCastException e) {
|
||||
e.printStackTrace();
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
||||
// Landroid/view/InputDevice;->isExternal()Z is officially public on Android Q
|
||||
return dev.isExternal();
|
||||
}
|
||||
else {
|
||||
try {
|
||||
// Landroid/view/InputDevice;->isExternal()Z is on the light graylist in Android P
|
||||
return (Boolean)dev.getClass().getMethod("isExternal").invoke(dev);
|
||||
} catch (NoSuchMethodException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
} catch (InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
} catch (ClassCastException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
// Answer true if we don't know
|
||||
|
||||
@@ -30,6 +30,18 @@ public abstract class AbstractXboxController extends AbstractController {
|
||||
private Thread createInputThread() {
|
||||
return new Thread() {
|
||||
public void run() {
|
||||
try {
|
||||
// Delay for a moment before reporting the new gamepad and
|
||||
// accepting new input. This allows time for the old InputDevice
|
||||
// to go away before we reclaim its spot. If the old device is still
|
||||
// around when we call notifyDeviceAdded(), we won't be able to claim
|
||||
// the controller number used by the original InputDevice.
|
||||
Thread.sleep(1000);
|
||||
} catch (InterruptedException e) {}
|
||||
|
||||
// Report that we're added _before_ reporting input
|
||||
notifyDeviceAdded();
|
||||
|
||||
while (!isInterrupted() && !stopped) {
|
||||
byte[] buffer = new byte[64];
|
||||
|
||||
@@ -114,9 +126,6 @@ public abstract class AbstractXboxController extends AbstractController {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Report that we're added _before_ starting the input thread
|
||||
notifyDeviceAdded();
|
||||
|
||||
// Start listening for controller input
|
||||
inputThread = createInputThread();
|
||||
inputThread.start();
|
||||
|
||||
@@ -474,6 +474,24 @@ public class MediaCodecHelper {
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static boolean isCodecBlacklisted(MediaCodecInfo codecInfo) {
|
||||
// Use the new isSoftwareOnly() function on Android Q
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
||||
if (codecInfo.isSoftwareOnly()) {
|
||||
LimeLog.info("Skipping software-only decoder: "+codecInfo.getName());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Check for explicitly blacklisted decoders
|
||||
if (isDecoderInList(blacklistedDecoderPrefixes, codecInfo.getName())) {
|
||||
LimeLog.info("Skipping blacklisted decoder: "+codecInfo.getName());
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static MediaCodecInfo findFirstDecoder(String mimeType) {
|
||||
for (MediaCodecInfo codecInfo : getMediaCodecList()) {
|
||||
@@ -482,15 +500,14 @@ public class MediaCodecHelper {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check for explicitly blacklisted decoders
|
||||
if (isDecoderInList(blacklistedDecoderPrefixes, codecInfo.getName())) {
|
||||
LimeLog.info("Skipping blacklisted decoder: "+codecInfo.getName());
|
||||
continue;
|
||||
}
|
||||
|
||||
// Find a decoder that supports the specified video format
|
||||
for (String mime : codecInfo.getSupportedTypes()) {
|
||||
if (mime.equalsIgnoreCase(mimeType)) {
|
||||
// Skip blacklisted codecs
|
||||
if (isCodecBlacklisted(codecInfo)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
LimeLog.info("First decoder choice is "+codecInfo.getName());
|
||||
return codecInfo;
|
||||
}
|
||||
@@ -530,17 +547,16 @@ public class MediaCodecHelper {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check for explicitly blacklisted decoders
|
||||
if (isDecoderInList(blacklistedDecoderPrefixes, codecInfo.getName())) {
|
||||
LimeLog.info("Skipping blacklisted decoder: "+codecInfo.getName());
|
||||
continue;
|
||||
}
|
||||
|
||||
// Find a decoder that supports the requested video format
|
||||
for (String mime : codecInfo.getSupportedTypes()) {
|
||||
if (mime.equalsIgnoreCase(mimeType)) {
|
||||
LimeLog.info("Examining decoder capabilities of "+codecInfo.getName());
|
||||
|
||||
// Skip blacklisted codecs
|
||||
if (isCodecBlacklisted(codecInfo)) {
|
||||
//continue;
|
||||
}
|
||||
|
||||
CodecCapabilities caps = codecInfo.getCapabilitiesForType(mime);
|
||||
|
||||
if (requiredProfile != -1) {
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
<resources>
|
||||
<style name="AppBaseTheme" parent="android:Theme.Material">
|
||||
<item name="android:navigationBarColor">@android:color/transparent</item>
|
||||
<item name="android:statusBarColor">@android:color/transparent</item>
|
||||
</style>
|
||||
</resources>
|
||||
Reference in New Issue
Block a user