diff options
Diffstat (limited to 'app/src/main/java/com/javispedro/vndroid/ScreenMirrorGrabber.java')
-rw-r--r-- | app/src/main/java/com/javispedro/vndroid/ScreenMirrorGrabber.java | 110 |
1 files changed, 110 insertions, 0 deletions
diff --git a/app/src/main/java/com/javispedro/vndroid/ScreenMirrorGrabber.java b/app/src/main/java/com/javispedro/vndroid/ScreenMirrorGrabber.java new file mode 100644 index 0000000..9f78b3c --- /dev/null +++ b/app/src/main/java/com/javispedro/vndroid/ScreenMirrorGrabber.java @@ -0,0 +1,110 @@ +package com.javispedro.vndroid; + +import android.content.Context; +import android.graphics.PixelFormat; +import android.hardware.display.DisplayManager; +import android.media.ImageReader; +import android.media.projection.MediaProjection; +import android.os.Handler; +import android.support.annotation.NonNull; +import android.util.DisplayMetrics; +import android.util.Log; +import android.view.Display; + +public class ScreenMirrorGrabber extends ScreenGrabber { + private static final String TAG = ScreenMirrorGrabber.class.getSimpleName(); + + protected final MediaProjection projection; + protected final Display realDisplay; + + protected final DisplayMetrics realDisplayMetrics; + + private float scale = 0.5f; + + public ScreenMirrorGrabber(Context context, @NonNull MediaProjection proj, @NonNull Display display) { + super(context); + projection = proj; + realDisplay = display; + realDisplayMetrics = new DisplayMetrics(); + } + + private void initDisplay() { + realDisplay.getRealMetrics(realDisplayMetrics); + + Log.d(TAG, "real display size: " + realDisplayMetrics.widthPixels + "x" + realDisplayMetrics.heightPixels); + + int width = Math.round(realDisplayMetrics.widthPixels * scale); + int height = Math.round(realDisplayMetrics.heightPixels * scale); + int dpi = realDisplayMetrics.densityDpi; + + Log.d(TAG, "starting mirror display with size: " + width + "x" + height + " dpi: " + dpi); + + reader = ImageReader.newInstance(width, height, PixelFormat.RGBA_8888, MAX_IMAGES); + reader.setOnImageAvailableListener(new ImageReaderCallback(), null); + + display = projection.createVirtualDisplay("vndroid", + width, height, dpi, + DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC | DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR, + reader.getSurface(), + new VirtualDisplayCallback(), null); + } + + @Override + public void start() { + if (reader != null || display != null) { + Log.w(TAG, "already started"); + return; + } + + initDisplay(); + } + + @Override + public void stop() { + super.stop(); + projection.stop(); + } + + @Override + public int scaleInputX(int x) { + return Math.round(x / scale); + } + + @Override + public int scaleInputY(int y) { + return Math.round(y / scale); + } + + @Override + public boolean hasSizeChanged() { + DisplayMetrics metrics = new DisplayMetrics(); + realDisplay.getRealMetrics(metrics); + return metrics.widthPixels != realDisplayMetrics.widthPixels || metrics.heightPixels != realDisplayMetrics.heightPixels; + } + + @Override + public void updateScreenSize() { + final ImageReader oldReader = reader; + reader = null; + + if (display != null) { + display.release(); + display = null; + } + + initDisplay(); + + Log.d(TAG, "new buffers set"); + + // Delay destruction of old image buffers to minimize multithread issues... + if (oldReader != null) { + new Handler().postDelayed(new Runnable() { + @Override + public void run() { + Log.d(TAG, "old buffers closed"); + oldReader.close(); + } + }, 1000); + } + } +} |