mirror of
https://github.com/moonlight-stream/moonlight-android.git
synced 2026-04-10 18:06:10 +00:00
Merge branch 'master' into virtualcontroller_master
Conflicts: app/app.iml app/build.gradle app/libs/limelight-common.jar app/src/main/java/com/limelight/Game.java app/src/main/java/com/limelight/binding/input/ControllerHandler.java app/src/main/java/com/limelight/binding/video/MediaCodecHelper.java app/src/main/java/com/limelight/computers/ComputerDatabaseManager.java app/src/main/java/com/limelight/preferences/PreferenceConfiguration.java app/src/main/jni/evdev_reader/evdev_reader.c app/src/main/res/xml/preferences.xml limelight-android.iml limelight_vc.iml moonlight-android.iml
This commit is contained in:
@@ -369,8 +369,10 @@ public class Game extends Activity implements SurfaceHolder.Callback,
|
||||
SpinnerDialog.closeDialogs(this);
|
||||
Dialog.closeDialogs();
|
||||
|
||||
InputManager inputManager = (InputManager) getSystemService(Context.INPUT_SERVICE);
|
||||
inputManager.unregisterInputDeviceListener(controllerHandler);
|
||||
if (controllerHandler != null) {
|
||||
InputManager inputManager = (InputManager) getSystemService(Context.INPUT_SERVICE);
|
||||
inputManager.unregisterInputDeviceListener(controllerHandler);
|
||||
}
|
||||
|
||||
wifiLock.release();
|
||||
|
||||
@@ -379,36 +381,38 @@ public class Game extends Activity implements SurfaceHolder.Callback,
|
||||
unbindService(usbDriverServiceConnection);
|
||||
}
|
||||
|
||||
VideoDecoderRenderer.VideoFormat videoFormat = conn.getActiveVideoFormat();
|
||||
if (conn != null) {
|
||||
VideoDecoderRenderer.VideoFormat videoFormat = conn.getActiveVideoFormat();
|
||||
|
||||
displayedFailureDialog = true;
|
||||
stopConnection();
|
||||
displayedFailureDialog = true;
|
||||
stopConnection();
|
||||
|
||||
int averageEndToEndLat = decoderRenderer.getAverageEndToEndLatency();
|
||||
int averageDecoderLat = decoderRenderer.getAverageDecoderLatency();
|
||||
String message = null;
|
||||
if (averageEndToEndLat > 0) {
|
||||
message = getResources().getString(R.string.conn_client_latency)+" "+averageEndToEndLat+" ms";
|
||||
if (averageDecoderLat > 0) {
|
||||
message += " ("+getResources().getString(R.string.conn_client_latency_hw)+" "+averageDecoderLat+" ms)";
|
||||
int averageEndToEndLat = decoderRenderer.getAverageEndToEndLatency();
|
||||
int averageDecoderLat = decoderRenderer.getAverageDecoderLatency();
|
||||
String message = null;
|
||||
if (averageEndToEndLat > 0) {
|
||||
message = getResources().getString(R.string.conn_client_latency)+" "+averageEndToEndLat+" ms";
|
||||
if (averageDecoderLat > 0) {
|
||||
message += " ("+getResources().getString(R.string.conn_client_latency_hw)+" "+averageDecoderLat+" ms)";
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (averageDecoderLat > 0) {
|
||||
message = getResources().getString(R.string.conn_hardware_latency)+" "+averageDecoderLat+" ms";
|
||||
}
|
||||
|
||||
// Add the video codec to the post-stream toast
|
||||
if (message != null && videoFormat != VideoDecoderRenderer.VideoFormat.Unknown) {
|
||||
if (videoFormat == VideoDecoderRenderer.VideoFormat.H265) {
|
||||
message += " [H.265]";
|
||||
else if (averageDecoderLat > 0) {
|
||||
message = getResources().getString(R.string.conn_hardware_latency)+" "+averageDecoderLat+" ms";
|
||||
}
|
||||
else {
|
||||
message += " [H.264]";
|
||||
}
|
||||
}
|
||||
|
||||
if (message != null) {
|
||||
Toast.makeText(this, message, Toast.LENGTH_LONG).show();
|
||||
// Add the video codec to the post-stream toast
|
||||
if (message != null && videoFormat != VideoDecoderRenderer.VideoFormat.Unknown) {
|
||||
if (videoFormat == VideoDecoderRenderer.VideoFormat.H265) {
|
||||
message += " [H.265]";
|
||||
}
|
||||
else {
|
||||
message += " [H.264]";
|
||||
}
|
||||
}
|
||||
|
||||
if (message != null) {
|
||||
Toast.makeText(this, message, Toast.LENGTH_LONG).show();
|
||||
}
|
||||
}
|
||||
|
||||
finish();
|
||||
|
||||
@@ -362,7 +362,7 @@ public class ControllerHandler implements InputManager.InputDeviceListener, UsbD
|
||||
}
|
||||
// Samsung's face buttons appear as a non-virtual button so we'll explicitly ignore
|
||||
// back presses on this device
|
||||
else if (devName.equals("sec_touchscreen")) {
|
||||
else if (devName.equals("sec_touchscreen") || devName.equals("sec_touchkey")) {
|
||||
context.ignoreBack = true;
|
||||
}
|
||||
// The Serval has a couple of unknown buttons that are start and select. It also has
|
||||
|
||||
@@ -76,14 +76,31 @@ public class MediaCodecHelper {
|
||||
|
||||
constrainedHighProfilePrefixes = new LinkedList<String>();
|
||||
constrainedHighProfilePrefixes.add("omx.intel");
|
||||
}
|
||||
|
||||
static {
|
||||
whitelistedHevcDecoders = new LinkedList<>();
|
||||
|
||||
// Exynos seems to be the only HEVC decoder that works reliably
|
||||
whitelistedHevcDecoders.add("omx.exynos");
|
||||
// whitelistedHevcDecoders.add("omx.nvidia"); TODO: This needs a similar fixup to the Tegra 3
|
||||
whitelistedHevcDecoders.add("omx.mtk");
|
||||
whitelistedHevcDecoders.add("omx.amlogic");
|
||||
whitelistedHevcDecoders.add("omx.rk");
|
||||
// omx.qcom added conditionally during initialization
|
||||
|
||||
// TODO: This needs a similar fixup to the Tegra 3 otherwise it buffers 16 frames
|
||||
//whitelistedHevcDecoders.add("omx.nvidia");
|
||||
|
||||
// Sony ATVs have broken MediaTek codecs (decoder hangs after rendering the first frame).
|
||||
// I know the Fire TV 2 works, so I'll just whitelist Amazon devices which seem
|
||||
// to actually be tested. Ugh...
|
||||
if (Build.MANUFACTURER.equalsIgnoreCase("Amazon")) {
|
||||
whitelistedHevcDecoders.add("omx.mtk");
|
||||
}
|
||||
|
||||
// These theoretically have good HEVC decoding capabilities (potentially better than
|
||||
// their AVC decoders), but haven't been tested enough
|
||||
//whitelistedHevcDecoders.add("omx.amlogic");
|
||||
//whitelistedHevcDecoders.add("omx.rk");
|
||||
|
||||
// Based on GPU attributes queried at runtime, the omx.qcom prefix will be added
|
||||
// during initialization to avoid SoCs with broken HEVC decoders.
|
||||
}
|
||||
|
||||
public static void initializeWithContext(Context context) {
|
||||
|
||||
@@ -53,7 +53,7 @@ public class ComputerDatabaseManager {
|
||||
}
|
||||
|
||||
public void deleteComputer(String name) {
|
||||
computerDb.delete(COMPUTER_TABLE_NAME, COMPUTER_NAME_COLUMN_NAME+"='"+name+"'", null);
|
||||
computerDb.delete(COMPUTER_TABLE_NAME, COMPUTER_NAME_COLUMN_NAME+"=?", new String[]{name});
|
||||
}
|
||||
|
||||
public boolean updateComputer(ComputerDetails details) {
|
||||
@@ -118,7 +118,7 @@ public class ComputerDatabaseManager {
|
||||
}
|
||||
|
||||
public ComputerDetails getComputerByName(String name) {
|
||||
Cursor c = computerDb.rawQuery("SELECT * FROM "+COMPUTER_TABLE_NAME+" WHERE "+COMPUTER_NAME_COLUMN_NAME+"='"+name+"'", null);
|
||||
Cursor c = computerDb.query(COMPUTER_TABLE_NAME, null, COMPUTER_NAME_COLUMN_NAME+"=?", new String[]{name}, null, null, null);
|
||||
ComputerDetails details = new ComputerDetails();
|
||||
if (!c.moveToFirst()) {
|
||||
// No matching computer
|
||||
|
||||
@@ -14,6 +14,8 @@
|
||||
|
||||
#include <android/log.h>
|
||||
|
||||
#define EVDEV_MAX_EVENT_SIZE 24
|
||||
|
||||
#define REL_X 0x00
|
||||
#define REL_Y 0x01
|
||||
#define KEY_Q 16
|
||||
@@ -69,7 +71,7 @@ void* pollThreadFunc(void* context) {
|
||||
struct DeviceEntry *device = context;
|
||||
struct pollfd pollinfo;
|
||||
int pollres, ret;
|
||||
char data[64];
|
||||
char data[EVDEV_MAX_EVENT_SIZE];
|
||||
|
||||
__android_log_print(ANDROID_LOG_INFO, "EvdevReader", "Polling /dev/input/%s", device->devName);
|
||||
|
||||
@@ -94,7 +96,7 @@ void* pollThreadFunc(void* context) {
|
||||
|
||||
if (pollres > 0 && (pollinfo.revents & POLLIN)) {
|
||||
// We'll have data available now
|
||||
ret = read(device->fd, data, sizeof(struct input_event));
|
||||
ret = read(device->fd, data, EVDEV_MAX_EVENT_SIZE);
|
||||
if (ret < 0) {
|
||||
__android_log_print(ANDROID_LOG_ERROR, "EvdevReader",
|
||||
"read() failed: %d", errno);
|
||||
@@ -132,6 +134,9 @@ cleanup:
|
||||
{
|
||||
struct DeviceEntry *lastEntry;
|
||||
|
||||
// Lock the device list
|
||||
pthread_mutex_lock(&DeviceListLock);
|
||||
|
||||
if (DeviceListHead == device) {
|
||||
DeviceListHead = device->next;
|
||||
}
|
||||
@@ -146,6 +151,9 @@ cleanup:
|
||||
lastEntry = lastEntry->next;
|
||||
}
|
||||
}
|
||||
|
||||
// Unlock device list
|
||||
pthread_mutex_unlock(&DeviceListLock);
|
||||
}
|
||||
|
||||
// Free the context
|
||||
@@ -254,6 +262,11 @@ static int enumerateDevices(void) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strstr(dirEnt->d_name, "event") == NULL) {
|
||||
// Skip non-event devices
|
||||
continue;
|
||||
}
|
||||
|
||||
startPollForDevice(dirEnt->d_name);
|
||||
}
|
||||
|
||||
@@ -269,6 +282,8 @@ int main(int argc, char* argv[]) {
|
||||
int pollres;
|
||||
struct pollfd pollinfo;
|
||||
|
||||
__android_log_print(ANDROID_LOG_INFO, "EvdevReader", "Entered main()");
|
||||
|
||||
// Perform initial enumeration
|
||||
ret = enumerateDevices();
|
||||
if (ret < 0) {
|
||||
@@ -293,33 +308,49 @@ int main(int argc, char* argv[]) {
|
||||
}
|
||||
while (pollres == 0);
|
||||
|
||||
ret = fread(&requestId, sizeof(requestId), 1, stdin);
|
||||
if (ret < sizeof(requestId)) {
|
||||
__android_log_print(ANDROID_LOG_ERROR, "EvdevReader", "Short read on input");
|
||||
return errno;
|
||||
}
|
||||
|
||||
if (requestId != UNGRAB_REQ && requestId != REGRAB_REQ) {
|
||||
__android_log_print(ANDROID_LOG_ERROR, "EvdevReader", "Unknown request");
|
||||
return requestId;
|
||||
}
|
||||
|
||||
{
|
||||
struct DeviceEntry *currentEntry;
|
||||
|
||||
pthread_mutex_lock(&DeviceListLock);
|
||||
|
||||
// Update state for future devices
|
||||
grabbing = (requestId == REGRAB_REQ);
|
||||
|
||||
// Carry out the requested action on each device
|
||||
currentEntry = DeviceListHead;
|
||||
while (currentEntry != NULL) {
|
||||
ioctl(currentEntry->fd, EVIOCGRAB, grabbing);
|
||||
currentEntry = currentEntry->next;
|
||||
if (pollres > 0 && (pollinfo.revents & POLLIN)) {
|
||||
// We'll have data available now
|
||||
ret = fread(&requestId, sizeof(requestId), 1, stdin);
|
||||
if (ret < sizeof(requestId)) {
|
||||
__android_log_print(ANDROID_LOG_ERROR, "EvdevReader", "Short read on input");
|
||||
return errno;
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&DeviceListLock);
|
||||
if (requestId != UNGRAB_REQ && requestId != REGRAB_REQ) {
|
||||
__android_log_print(ANDROID_LOG_ERROR, "EvdevReader", "Unknown request");
|
||||
return requestId;
|
||||
}
|
||||
|
||||
{
|
||||
struct DeviceEntry *currentEntry;
|
||||
|
||||
pthread_mutex_lock(&DeviceListLock);
|
||||
|
||||
// Update state for future devices
|
||||
grabbing = (requestId == REGRAB_REQ);
|
||||
|
||||
// Carry out the requested action on each device
|
||||
currentEntry = DeviceListHead;
|
||||
while (currentEntry != NULL) {
|
||||
ioctl(currentEntry->fd, EVIOCGRAB, grabbing);
|
||||
currentEntry = currentEntry->next;
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&DeviceListLock);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Terminate this thread
|
||||
if (pollres < 0) {
|
||||
__android_log_print(ANDROID_LOG_ERROR, "EvdevReader",
|
||||
"Stdin poll() failed: %d", errno);
|
||||
}
|
||||
else {
|
||||
__android_log_print(ANDROID_LOG_ERROR, "EvdevReader",
|
||||
"Stdin unexpected revents: %d", pollinfo.revents);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user