summaryrefslogtreecommitdiff
path: root/app/src/main/java/com/javispedro/vndroid/ServerService.java
diff options
context:
space:
mode:
Diffstat (limited to 'app/src/main/java/com/javispedro/vndroid/ServerService.java')
-rw-r--r--app/src/main/java/com/javispedro/vndroid/ServerService.java230
1 files changed, 159 insertions, 71 deletions
diff --git a/app/src/main/java/com/javispedro/vndroid/ServerService.java b/app/src/main/java/com/javispedro/vndroid/ServerService.java
index bf72d21..96420df 100644
--- a/app/src/main/java/com/javispedro/vndroid/ServerService.java
+++ b/app/src/main/java/com/javispedro/vndroid/ServerService.java
@@ -1,61 +1,80 @@
package com.javispedro.vndroid;
-import android.app.Activity;
import android.app.Notification;
import android.app.Service;
import android.content.Intent;
import android.content.res.Configuration;
import android.media.Image;
-import android.media.projection.MediaProjection;
-import android.media.projection.MediaProjectionManager;
+import android.os.Binder;
import android.os.IBinder;
import android.util.Log;
-import android.view.WindowManager;
import android.widget.Toast;
import com.javispedro.vndroid.keymaps.AndroidKeyHandler;
import com.javispedro.vndroid.keymaps.SpanishKeyHandler;
+import java.lang.ref.WeakReference;
+import java.net.InetAddress;
+import java.net.NetworkInterface;
+import java.util.Enumeration;
+import java.util.LinkedList;
+import java.util.List;
+
public class ServerService extends Service {
private static final String TAG = ServerService.class.getSimpleName();
- public static final String ACTION_START = "ACTION_START";
- public static final String ACTION_STOP = "ACTION_STOP";
- public static final String ACTION_NOTIFY_MEDIA_PROJECTION_RESULT = "ACTION_NOTIFY_MEDIA_PROJECTION_RESULT";
+
+ public static final String ACTION_START_SERVER = "ACTION_START_SERVER";
+ public static final String ACTION_STOP_SERVER = "ACTION_STOP_SERVER";
+
+ public class ServerBinder extends Binder {
+ ServerService getService() {
+ return ServerService.this;
+ }
+ }
+ public interface ServerStatusCallback {
+ void onServerStatusChanged();
+ void onNumClientChanged();
+ }
+
+ private ServerBinder binder;
+ private WeakReference<ServerStatusCallback> callback;
private ScreenGrabber screenGrabber;
private RFBServer rfbServer;
private PointerEventOutput pointerOut;
private KeyEventOutput keyOut;
- public ServerService() {
- }
-
@Override
public void onCreate() {
+ Log.d(TAG, "onCreate");
+ binder = new ServerBinder();
ServerRunningNotification.initNotificationChannel(this);
System.loadLibrary("native-lib");
}
@Override
+ public void onDestroy() {
+ Log.d(TAG, "onDestroy");
+ cleanupServer();
+ binder = null;
+ callback = null;
+ }
+
+ @Override
public IBinder onBind(Intent intent) {
- throw new UnsupportedOperationException("Not implemented");
+ return binder;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
- if (intent != null) {
- switch (intent.getAction()) {
- case ACTION_START:
- start();
- break;
- case ACTION_STOP:
- stop();
- break;
- case ACTION_NOTIFY_MEDIA_PROJECTION_RESULT:
- notifyMediaProjectionResult(intent.getIntExtra("resultCode", Activity.RESULT_CANCELED),
- (Intent) intent.getParcelableExtra("resultData"));
- break;
- }
+ Log.d(TAG, "onStartCommand intent=" + intent);
+ switch (intent.getAction()) {
+ case ACTION_START_SERVER:
+ startServer();
+ return START_REDELIVER_INTENT;
+ case ACTION_STOP_SERVER:
+ stopServer();
+ return START_NOT_STICKY;
}
return super.onStartCommand(intent, flags, startId);
}
@@ -69,43 +88,15 @@ public class ServerService extends Service {
}
}
- protected class ScreenGrabberCallback implements ScreenGrabber.Callback {
- @Override
- public void onImage(Image image) {
- if (rfbServer != null) {
- rfbServer.putImage(image);
- } else {
- image.close();
- }
+ public void setServerStatusCallback(ServerStatusCallback callback) {
+ if (callback != null) {
+ this.callback = new WeakReference<>(callback);
+ } else {
+ this.callback = null;
}
}
- protected class EventCallback implements RFBServer.EventCallback {
- @Override
- public void onPointerEvent(int buttonMask, int x, int y) {
- try {
- x = screenGrabber.scaleInputX(x);
- y = screenGrabber.scaleInputY(y);
- pointerOut.postPointerEvent((byte) buttonMask, x, y);
- } catch (Exception e) {
- Log.e(TAG, "Exception on pointer EventCallback: " + e.toString());
- e.printStackTrace();
- // Need to supress the exception, otherwise we'll crash JNI
- }
- }
-
- @Override
- public void onKeyEvent(int key, boolean state) {
- try {
- keyOut.postKeyEvent(key, state);
- } catch (Exception e) {
- Log.e(TAG, "Exception on key EventCallback: " + e.toString());
- e.printStackTrace();
- }
- }
- }
-
- protected void start() {
+ public void startServer() {
if (rfbServer != null) {
Log.w(TAG, "cannot start, already started");
return;
@@ -113,6 +104,9 @@ public class ServerService extends Service {
Log.d(TAG, "starting");
+ Notification notification = ServerRunningNotification.build(this);
+ startForeground(1, notification);
+
if (!ControlService.isServiceStarted()) {
Toast toast = Toast.makeText(this, R.string.toast_no_input_service, Toast.LENGTH_SHORT);
toast.show();
@@ -123,7 +117,6 @@ public class ServerService extends Service {
keyOut.addHandler(new AndroidKeyHandler());
keyOut.addHandler(new SpanishKeyHandler());
-
if (screenGrabber == null) {
screenGrabber = new ScreenVirtualGrabber(this);
}
@@ -135,13 +128,61 @@ public class ServerService extends Service {
screenGrabber.setCallback(new ScreenGrabberCallback());
screenGrabber.start();
- Notification notification = ServerRunningNotification.build(this);
- startForeground(1, notification);
+ notifyServerStatusChanged();
}
- protected void stop() {
+ public void stopServer() {
Log.d(TAG, "stopping");
+ cleanupServer();
+
+ stopForeground(true);
+ stopSelf();
+
+ notifyServerStatusChanged();
+ }
+
+ public boolean isServerActive() {
+ return rfbServer != null;
+ }
+
+ public void setMediaProjectionResult(int resultCode, Intent data) {
+ if (screenGrabber != null) {
+ Log.w(TAG, "already have an screen grabber");
+ }
+
+ screenGrabber = new ScreenMirrorGrabber(this, resultCode, data);
+ }
+
+ public int getListeningDisplay() {
+ return 0;
+ }
+
+ public List<String> getListeningIPAddresses() {
+ LinkedList<String> result = new LinkedList<String>();
+ try {
+ for (Enumeration<NetworkInterface> netif_it = NetworkInterface.getNetworkInterfaces(); netif_it.hasMoreElements(); ) {
+ NetworkInterface netif = netif_it.nextElement();
+
+ for (Enumeration<InetAddress> addr_it = netif.getInetAddresses(); addr_it.hasMoreElements(); ) {
+ InetAddress addr = addr_it.nextElement();
+
+ if (addr.isLoopbackAddress()) continue;
+
+ result.add(addr.getHostAddress());
+ }
+ }
+ } catch (Exception ex) {
+ Log.w(TAG, "While enumerating IP addresses: " + ex.toString());
+ }
+ return result;
+ }
+
+ public int getNumClients() {
+ return rfbServer.getNumClients();
+ }
+
+ private void cleanupServer() {
if (rfbServer != null) {
rfbServer.stop();
rfbServer = null;
@@ -156,20 +197,67 @@ public class ServerService extends Service {
if (keyOut != null) {
keyOut = null;
}
+ }
- stopForeground(true);
- stopSelf();
+ private ServerStatusCallback getStatusCallback() {
+ return callback == null ? null : callback.get();
}
- protected void notifyMediaProjectionResult(int resultCode, Intent data) {
- if (screenGrabber != null) {
- Log.w(TAG, "already have an screen grabber");
+ private void notifyServerStatusChanged() {
+ ServerStatusCallback cb = getStatusCallback();
+ if (cb == null) return;
+ cb.onServerStatusChanged();
+ }
+
+ private void notifyNumClientChanged() {
+ ServerStatusCallback cb = getStatusCallback();
+ if (cb == null) return;
+ cb.onNumClientChanged();
+ }
+
+ private class ScreenGrabberCallback implements ScreenGrabber.Callback {
+ @Override
+ public void onImage(Image image) {
+ if (rfbServer != null) {
+ rfbServer.putImage(image);
+ } else {
+ image.close();
+ }
}
- MediaProjectionManager manager = getSystemService(MediaProjectionManager.class);
- MediaProjection projection = manager.getMediaProjection(resultCode, data);
+ }
- WindowManager wm = getSystemService(WindowManager.class);
+ private class EventCallback implements RFBServer.EventCallback {
+ @Override
+ public void onPointerEvent(int buttonMask, int x, int y) {
+ try {
+ x = screenGrabber.scaleInputX(x);
+ y = screenGrabber.scaleInputY(y);
+ pointerOut.postPointerEvent((byte) buttonMask, x, y);
+ } catch (Exception e) {
+ Log.e(TAG, "Exception on pointer EventCallback: " + e.toString());
+ e.printStackTrace();
+ // Need to suppress the exception, otherwise we'll crash JNI
+ }
+ }
- screenGrabber = new ScreenMirrorGrabber(this, projection, wm.getDefaultDisplay());
+ @Override
+ public void onKeyEvent(int key, boolean state) {
+ try {
+ keyOut.postKeyEvent(key, state);
+ } catch (Exception e) {
+ Log.e(TAG, "Exception on key EventCallback: " + e.toString());
+ e.printStackTrace();
+ }
+ }
+
+ @Override
+ public void onClientEvent() {
+ try {
+ notifyNumClientChanged();
+ } catch (Exception e) {
+ Log.e(TAG, "Exception on client EventCallback: " + e.toString());
+ e.printStackTrace();
+ }
+ }
}
}