From 2f74ec2518377103e144684a9fb0c2d358168bbb Mon Sep 17 00:00:00 2001 From: Romain Vimont Date: Sat, 2 May 2020 00:39:40 +0200 Subject: [PATCH] Add a clean up process on the device In order to clean up on close, use a separate process which is not killed when the device is disconnected (even if the main process itself is killed). --- .../java/com/genymobile/scrcpy/CleanUp.java | 62 +++++++++++++++++++ .../java/com/genymobile/scrcpy/Server.java | 14 +---- 2 files changed, 65 insertions(+), 11 deletions(-) create mode 100644 server/src/main/java/com/genymobile/scrcpy/CleanUp.java diff --git a/server/src/main/java/com/genymobile/scrcpy/CleanUp.java b/server/src/main/java/com/genymobile/scrcpy/CleanUp.java new file mode 100644 index 00000000..ca16cc3d --- /dev/null +++ b/server/src/main/java/com/genymobile/scrcpy/CleanUp.java @@ -0,0 +1,62 @@ +package com.genymobile.scrcpy; + +import com.genymobile.scrcpy.wrappers.ContentProvider; +import com.genymobile.scrcpy.wrappers.ServiceManager; + +import java.io.File; +import java.io.IOException; + +/** + * Handle the cleanup of scrcpy, even if the main process is killed. + *

+ * This is useful to restore some state when scrcpy is closed, even on device disconnection (which kills the scrcpy process). + */ +public final class CleanUp { + + public static final String SERVER_PATH = "/data/local/tmp/scrcpy-server.jar"; + + private CleanUp() { + // not instantiable + } + + public static void configure() throws IOException { + // TODO + boolean needProcess = false; + if (needProcess) { + startProcess(); + } else { + // There is no additional clean up to do when scrcpy dies + unlinkSelf(); + } + } + + private static void startProcess() throws IOException { + String[] cmd = {"app_process", "/", CleanUp.class.getName()}; + + ProcessBuilder builder = new ProcessBuilder(cmd); + builder.environment().put("CLASSPATH", SERVER_PATH); + builder.start(); + } + + private static void unlinkSelf() { + try { + new File(SERVER_PATH).delete(); + } catch (Exception e) { + Ln.e("Could not unlink server", e); + } + } + + public static void main(String... args) { + unlinkSelf(); + + try { + // Wait for the server to die + System.in.read(); + } catch (IOException e) { + // Expected when the server is dead + } + + Ln.i("Cleaning up"); + // TODO + } +} diff --git a/server/src/main/java/com/genymobile/scrcpy/Server.java b/server/src/main/java/com/genymobile/scrcpy/Server.java index a6f7a78c..4ac961de 100644 --- a/server/src/main/java/com/genymobile/scrcpy/Server.java +++ b/server/src/main/java/com/genymobile/scrcpy/Server.java @@ -4,12 +4,10 @@ import android.graphics.Rect; import android.media.MediaCodec; import android.os.Build; -import java.io.File; import java.io.IOException; public final class Server { - private static final String SERVER_PATH = "/data/local/tmp/scrcpy-server.jar"; private Server() { // not instantiable @@ -18,6 +16,9 @@ public final class Server { private static void scrcpy(Options options) throws IOException { Ln.i("Device: " + Build.MANUFACTURER + " " + Build.MODEL + " (Android " + Build.VERSION.RELEASE + ")"); final Device device = new Device(options); + + CleanUp.configure(); + boolean tunnelForward = options.isTunnelForward(); try (DesktopConnection connection = DesktopConnection.open(device, tunnelForward)) { ScreenEncoder screenEncoder = new ScreenEncoder(options.getSendFrameMeta(), options.getBitRate(), options.getMaxFps()); @@ -132,14 +133,6 @@ public final class Server { return new Rect(x, y, x + width, y + height); } - private static void unlinkSelf() { - try { - new File(SERVER_PATH).delete(); - } catch (Exception e) { - Ln.e("Could not unlink server", e); - } - } - private static void suggestFix(Throwable e) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { if (e instanceof MediaCodec.CodecException) { @@ -172,7 +165,6 @@ public final class Server { } }); - unlinkSelf(); Options options = createOptions(args); scrcpy(options); }