Compare commits

..

3 Commits

Author SHA1 Message Date
Yu-Chen Lin
f24d488ca2 Check client and server mismatch
Send client version as first parameter and check it at server start.

Signed-off-by: Yu-Chen Lin <npes87184@gmail.com>
Signed-off-by: Romain Vimont <rom@rom1v.com>
2019-11-11 14:43:16 +01:00
Romain Vimont
6996cbf5d3 Log device disconnection
If scrcpy closes due to socket disconnection, log a warning.
2019-11-09 21:17:03 +01:00
olbb
e282100d0b Call Looper.prepareMainLooper() to avoid exception
Some devices internally create a Handler when creating an input Surface,
causing an exception:

> Surface: java.lang.RuntimeException: Can't create handler inside
> thread that has not called Looper.prepare()

As a workaround, call Looper.prepareMainLooper() beforehand.

Fixes:
 - <https://github.com/Genymobile/scrcpy/issues/240>
 - <https://github.com/Genymobile/scrcpy/issues/921>

Signed-off-by: Romain Vimont <rom@rom1v.com>
2019-11-09 20:31:57 +01:00
4 changed files with 26 additions and 9 deletions

View File

@@ -218,6 +218,7 @@ event_loop(bool display, bool control) {
case EVENT_RESULT_STOPPED_BY_USER: case EVENT_RESULT_STOPPED_BY_USER:
return true; return true;
case EVENT_RESULT_STOPPED_BY_EOS: case EVENT_RESULT_STOPPED_BY_EOS:
LOGW("Device disconnected");
return false; return false;
case EVENT_RESULT_CONTINUE: case EVENT_RESULT_CONTINUE:
break; break;

View File

@@ -131,6 +131,7 @@ execute_server(struct server *server, const struct server_params *params) {
#endif #endif
"/", // unused "/", // unused
"com.genymobile.scrcpy.Server", "com.genymobile.scrcpy.Server",
SCRCPY_VERSION,
max_size_string, max_size_string,
bit_rate_string, bit_rate_string,
server->tunnel_forward ? "true" : "false", server->tunnel_forward ? "true" : "false",

View File

@@ -56,8 +56,13 @@ public class ScreenEncoder implements Device.RotationListener {
public void streamScreen(Device device, FileDescriptor fd) throws IOException { public void streamScreen(Device device, FileDescriptor fd) throws IOException {
// Some devices internally create a Handler when creating an input Surface, causing an exception: // Some devices internally create a Handler when creating an input Surface, causing an exception:
// "Can't create handler inside thread that has not called Looper.prepare()" // "Can't create handler inside thread that has not called Looper.prepare()"
// <https://github.com/Genymobile/scrcpy/issues/240> // <https://github.com/Genymobile/scrcpy/issues/240>
//
// Use Looper.prepareMainLooper() instead of Looper.prepare() to avoid a NullPointerException:
// "Attempt to read from field 'android.os.MessageQueue android.os.Looper.mQueue'
// on a null object reference"
// <https://github.com/Genymobile/scrcpy/issues/921>
Looper.prepareMainLooper(); Looper.prepareMainLooper();
MediaFormat format = createFormat(bitRate, frameRate, iFrameInterval); MediaFormat format = createFormat(bitRate, frameRate, iFrameInterval);

View File

@@ -67,29 +67,39 @@ public final class Server {
@SuppressWarnings("checkstyle:MagicNumber") @SuppressWarnings("checkstyle:MagicNumber")
private static Options createOptions(String... args) { private static Options createOptions(String... args) {
if (args.length != 6) { if (args.length < 1) {
throw new IllegalArgumentException("Expecting 6 parameters"); throw new IllegalArgumentException("Missing client version");
}
String clientVersion = args[0];
if (!clientVersion.equals(BuildConfig.VERSION_NAME)) {
throw new IllegalArgumentException("The server version (" + clientVersion + ") does not match the client "
+ "(" + BuildConfig.VERSION_NAME + ")");
}
if (args.length != 7) {
throw new IllegalArgumentException("Expecting 7 parameters");
} }
Options options = new Options(); Options options = new Options();
int maxSize = Integer.parseInt(args[0]) & ~7; // multiple of 8 int maxSize = Integer.parseInt(args[1]) & ~7; // multiple of 8
options.setMaxSize(maxSize); options.setMaxSize(maxSize);
int bitRate = Integer.parseInt(args[1]); int bitRate = Integer.parseInt(args[2]);
options.setBitRate(bitRate); options.setBitRate(bitRate);
// use "adb forward" instead of "adb tunnel"? (so the server must listen) // use "adb forward" instead of "adb tunnel"? (so the server must listen)
boolean tunnelForward = Boolean.parseBoolean(args[2]); boolean tunnelForward = Boolean.parseBoolean(args[3]);
options.setTunnelForward(tunnelForward); options.setTunnelForward(tunnelForward);
Rect crop = parseCrop(args[3]); Rect crop = parseCrop(args[4]);
options.setCrop(crop); options.setCrop(crop);
boolean sendFrameMeta = Boolean.parseBoolean(args[4]); boolean sendFrameMeta = Boolean.parseBoolean(args[5]);
options.setSendFrameMeta(sendFrameMeta); options.setSendFrameMeta(sendFrameMeta);
boolean control = Boolean.parseBoolean(args[5]); boolean control = Boolean.parseBoolean(args[6]);
options.setControl(control); options.setControl(control);
return options; return options;