mirror of
https://github.com/Genymobile/scrcpy.git
synced 2025-08-08 00:59:47 +00:00
Apply Genymobile rules for Android projects
Apply Genymobile checkstyle and gradle build files organization.
This commit is contained in:
parent
285fc97d02
commit
e55e42a442
19 changed files with 299 additions and 52 deletions
|
@ -1,11 +1,11 @@
|
|||
apply plugin: 'com.android.application'
|
||||
|
||||
android {
|
||||
compileSdkVersion 26
|
||||
compileSdkVersion 27
|
||||
defaultConfig {
|
||||
applicationId "com.genymobile.scrcpy"
|
||||
minSdkVersion 21
|
||||
targetSdkVersion 26
|
||||
targetSdkVersion 27
|
||||
versionCode 1
|
||||
versionName "1.0"
|
||||
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
||||
|
@ -22,3 +22,5 @@ dependencies {
|
|||
implementation fileTree(dir: 'libs', include: ['*.jar'])
|
||||
testImplementation 'junit:junit:4.12'
|
||||
}
|
||||
|
||||
apply from: "$project.rootDir/config/android-checkstyle.gradle"
|
||||
|
|
|
@ -3,7 +3,7 @@ package com.genymobile.scrcpy;
|
|||
/**
|
||||
* Union of all supported event types, identified by their {@code type}.
|
||||
*/
|
||||
public class ControlEvent {
|
||||
public final class ControlEvent {
|
||||
|
||||
public static final int TYPE_KEYCODE = 0;
|
||||
public static final int TYPE_TEXT = 1;
|
||||
|
|
|
@ -12,9 +12,12 @@ public class ControlEventReader {
|
|||
private static final int SCROLL_PAYLOAD_LENGTH = 16;
|
||||
private static final int COMMAND_PAYLOAD_LENGTH = 1;
|
||||
|
||||
private final byte[] rawBuffer = new byte[128];
|
||||
private static final int MAX_TEXT_LENGTH = 32;
|
||||
private static final int RAW_BUFFER_SIZE = 128;
|
||||
|
||||
private final byte[] rawBuffer = new byte[RAW_BUFFER_SIZE];
|
||||
private final ByteBuffer buffer = ByteBuffer.wrap(rawBuffer);
|
||||
private final byte[] textBuffer = new byte[32];
|
||||
private final byte[] textBuffer = new byte[MAX_TEXT_LENGTH];
|
||||
|
||||
public ControlEventReader() {
|
||||
// invariant: the buffer is always in "get" mode
|
||||
|
@ -136,10 +139,12 @@ public class ControlEventReader {
|
|||
return new Position(x, y, screenWidth, screenHeight);
|
||||
}
|
||||
|
||||
@SuppressWarnings("checkstyle:MagicNumber")
|
||||
private static int toUnsigned(short value) {
|
||||
return value & 0xffff;
|
||||
}
|
||||
|
||||
@SuppressWarnings("checkstyle:MagicNumber")
|
||||
private static int toUnsigned(byte value) {
|
||||
return value & 0xff;
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ import java.io.InputStream;
|
|||
import java.io.OutputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
public class DesktopConnection implements Closeable {
|
||||
public final class DesktopConnection implements Closeable {
|
||||
|
||||
private static final int DEVICE_NAME_FIELD_LENGTH = 64;
|
||||
|
||||
|
@ -48,9 +48,8 @@ public class DesktopConnection implements Closeable {
|
|||
socket.close();
|
||||
}
|
||||
|
||||
@SuppressWarnings("checkstyle:MagicNumber")
|
||||
private void send(String deviceName, int width, int height) throws IOException {
|
||||
assert width < 0x10000 : "width may not be stored on 16 bits";
|
||||
assert height < 0x10000 : "height may not be stored on 16 bits";
|
||||
byte[] buffer = new byte[DEVICE_NAME_FIELD_LENGTH + 4];
|
||||
|
||||
byte[] deviceNameBytes = deviceName.getBytes(StandardCharsets.UTF_8);
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
package com.genymobile.scrcpy;
|
||||
|
||||
import com.genymobile.scrcpy.wrappers.ServiceManager;
|
||||
|
||||
import android.graphics.Point;
|
||||
import android.os.Build;
|
||||
import android.os.RemoteException;
|
||||
import android.view.IRotationWatcher;
|
||||
import android.view.InputEvent;
|
||||
|
||||
import com.genymobile.scrcpy.wrappers.ServiceManager;
|
||||
|
||||
public final class Device {
|
||||
|
||||
public interface RotationListener {
|
||||
|
@ -40,6 +40,7 @@ public final class Device {
|
|||
return screenInfo;
|
||||
}
|
||||
|
||||
@SuppressWarnings("checkstyle:MagicNumber")
|
||||
private ScreenInfo computeScreenInfo(int maxSize) {
|
||||
// Compute the video size and the padding of the content inside this video.
|
||||
// Principle:
|
||||
|
@ -52,7 +53,9 @@ public final class Device {
|
|||
int w = deviceSize.getWidth();
|
||||
int h = deviceSize.getHeight();
|
||||
if (maxSize > 0) {
|
||||
assert maxSize % 8 == 0;
|
||||
if (BuildConfig.DEBUG && maxSize % 8 != 0) {
|
||||
throw new AssertionError("Max size must be a multiple of 8");
|
||||
}
|
||||
boolean portrait = h > w;
|
||||
int major = portrait ? h : w;
|
||||
int minor = portrait ? w : h;
|
||||
|
@ -70,6 +73,7 @@ public final class Device {
|
|||
}
|
||||
|
||||
public Point getPhysicalPoint(Position position) {
|
||||
@SuppressWarnings("checkstyle:HiddenField") // it hides the field on purpose, to read it with a lock
|
||||
ScreenInfo screenInfo = getScreenInfo(); // read with synchronization
|
||||
Size videoSize = screenInfo.getVideoSize();
|
||||
Size clientVideoSize = position.getScreenSize();
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package com.genymobile.scrcpy;
|
||||
|
||||
import com.genymobile.scrcpy.wrappers.InputManager;
|
||||
|
||||
import android.graphics.Point;
|
||||
import android.os.SystemClock;
|
||||
import android.view.InputDevice;
|
||||
|
@ -8,10 +10,9 @@ import android.view.KeyCharacterMap;
|
|||
import android.view.KeyEvent;
|
||||
import android.view.MotionEvent;
|
||||
|
||||
import com.genymobile.scrcpy.wrappers.InputManager;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
|
||||
public class EventController {
|
||||
|
||||
private final Device device;
|
||||
|
@ -83,6 +84,8 @@ public class EventController {
|
|||
case ControlEvent.TYPE_COMMAND:
|
||||
executeCommand(controlEvent.getAction());
|
||||
break;
|
||||
default:
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -157,6 +160,8 @@ public class EventController {
|
|||
switch (action) {
|
||||
case ControlEvent.COMMAND_SCREEN_ON:
|
||||
return turnScreenOn();
|
||||
default:
|
||||
Ln.w("Unsupported command: " + action);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ import android.util.Log;
|
|||
* Log both to Android logger (so that logs are visible in "adb logcat") and standard output/error (so that they are visible in the terminal
|
||||
* directly).
|
||||
*/
|
||||
public class Ln {
|
||||
public final class Ln {
|
||||
|
||||
private static final String TAG = "scrcpy";
|
||||
|
||||
|
|
|
@ -27,11 +27,15 @@ public class Position {
|
|||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
Position position = (Position) o;
|
||||
return Objects.equals(point, position.point) &&
|
||||
Objects.equals(screenSize, position.screenSize);
|
||||
return Objects.equals(point, position.point)
|
||||
&& Objects.equals(screenSize, position.screenSize);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -41,10 +45,10 @@ public class Position {
|
|||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Position{" +
|
||||
"point=" + point +
|
||||
", screenSize=" + screenSize +
|
||||
'}';
|
||||
return "Position{"
|
||||
+ "point=" + point
|
||||
+ ", screenSize=" + screenSize
|
||||
+ '}';
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -2,7 +2,11 @@ package com.genymobile.scrcpy;
|
|||
|
||||
import java.io.IOException;
|
||||
|
||||
public class ScrCpyServer {
|
||||
public final class ScrCpyServer {
|
||||
|
||||
private ScrCpyServer() {
|
||||
// not instantiable
|
||||
}
|
||||
|
||||
private static void scrcpy(Options options) throws IOException {
|
||||
final Device device = new Device(options);
|
||||
|
@ -34,6 +38,7 @@ public class ScrCpyServer {
|
|||
}).start();
|
||||
}
|
||||
|
||||
@SuppressWarnings("checkstyle:MagicNumber")
|
||||
private static Options createOptions(String... args) {
|
||||
Options options = new Options();
|
||||
if (args.length < 1) {
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package com.genymobile.scrcpy;
|
||||
|
||||
import com.genymobile.scrcpy.wrappers.SurfaceControl;
|
||||
|
||||
import android.graphics.Rect;
|
||||
import android.media.MediaCodec;
|
||||
import android.media.MediaCodecInfo;
|
||||
|
@ -7,8 +9,6 @@ import android.media.MediaFormat;
|
|||
import android.os.IBinder;
|
||||
import android.view.Surface;
|
||||
|
||||
import com.genymobile.scrcpy.wrappers.SurfaceControl;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.nio.ByteBuffer;
|
||||
|
@ -22,6 +22,8 @@ public class ScreenEncoder implements Device.RotationListener {
|
|||
|
||||
private static final int REPEAT_FRAME_DELAY = 6; // repeat after 6 frames
|
||||
|
||||
private static final int MICROSECONDS_IN_ONE_SECOND = 1_000_000;
|
||||
|
||||
private final AtomicBoolean rotationChanged = new AtomicBoolean();
|
||||
|
||||
private int bitRate;
|
||||
|
@ -81,6 +83,7 @@ public class ScreenEncoder implements Device.RotationListener {
|
|||
}
|
||||
|
||||
private boolean encode(MediaCodec codec, OutputStream outputStream) throws IOException {
|
||||
@SuppressWarnings("checkstyle:MagicNumber")
|
||||
byte[] buf = new byte[bitRate / 8]; // may contain up to 1 second of video
|
||||
boolean eof = false;
|
||||
MediaCodec.BufferInfo bufferInfo = new MediaCodec.BufferInfo();
|
||||
|
@ -124,7 +127,7 @@ public class ScreenEncoder implements Device.RotationListener {
|
|||
format.setInteger(MediaFormat.KEY_COLOR_FORMAT, MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface);
|
||||
format.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, iFrameInterval);
|
||||
// display the very first frame, and recover from bad quality when no new frames
|
||||
format.setLong(MediaFormat.KEY_REPEAT_PREVIOUS_FRAME_AFTER, 1_000_000 * REPEAT_FRAME_DELAY / frameRate); // µs
|
||||
format.setLong(MediaFormat.KEY_REPEAT_PREVIOUS_FRAME_AFTER, MICROSECONDS_IN_ONE_SECOND * REPEAT_FRAME_DELAY / frameRate); // µs
|
||||
return format;
|
||||
}
|
||||
|
||||
|
|
|
@ -31,11 +31,15 @@ public final class Size {
|
|||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
Size size = (Size) o;
|
||||
return width == size.width &&
|
||||
height == size.height;
|
||||
return width == size.width
|
||||
&& height == size.height;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -45,9 +49,9 @@ public final class Size {
|
|||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Size{" +
|
||||
"width=" + width +
|
||||
", height=" + height +
|
||||
'}';
|
||||
return "Size{"
|
||||
+ "width=" + width
|
||||
+ ", height=" + height
|
||||
+ '}';
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
package com.genymobile.scrcpy.wrappers;
|
||||
|
||||
import android.os.IInterface;
|
||||
|
||||
import com.genymobile.scrcpy.DisplayInfo;
|
||||
import com.genymobile.scrcpy.Size;
|
||||
|
||||
public class DisplayManager {
|
||||
import android.os.IInterface;
|
||||
|
||||
public final class DisplayManager {
|
||||
private final IInterface manager;
|
||||
|
||||
public DisplayManager(IInterface manager) {
|
||||
|
|
|
@ -6,7 +6,7 @@ import android.view.InputEvent;
|
|||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
public class InputManager {
|
||||
public final class InputManager {
|
||||
|
||||
public static final int INJECT_INPUT_EVENT_MODE_ASYNC = 0;
|
||||
public static final int INJECT_INPUT_EVENT_MODE_WAIT_FOR_RESULT = 1;
|
||||
|
|
|
@ -1,19 +1,21 @@
|
|||
package com.genymobile.scrcpy.wrappers;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.os.Build;
|
||||
import android.os.IInterface;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
public class PowerManager {
|
||||
public final class PowerManager {
|
||||
private final IInterface manager;
|
||||
private final Method isScreenOnMethod;
|
||||
|
||||
public PowerManager(IInterface manager) {
|
||||
this.manager = manager;
|
||||
try {
|
||||
String methodName = Build.VERSION.SDK_INT >= 20 ? "isInteractive" : "isScreenOn";
|
||||
@SuppressLint("ObsoleteSdkInt") // we may lower minSdkVersion in the future
|
||||
String methodName = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT_WATCH ? "isInteractive" : "isScreenOn";
|
||||
isScreenOnMethod = manager.getClass().getMethod(methodName);
|
||||
} catch (NoSuchMethodException e) {
|
||||
throw new AssertionError(e);
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
package com.genymobile.scrcpy.wrappers;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.os.IBinder;
|
||||
import android.os.IInterface;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
public class ServiceManager {
|
||||
@SuppressLint("PrivateApi")
|
||||
public final class ServiceManager {
|
||||
private final Method getServiceMethod;
|
||||
|
||||
private WindowManager windowManager;
|
||||
|
|
|
@ -1,16 +1,18 @@
|
|||
package com.genymobile.scrcpy.wrappers;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.graphics.Rect;
|
||||
import android.os.IBinder;
|
||||
import android.view.Surface;
|
||||
|
||||
public class SurfaceControl {
|
||||
@SuppressLint("PrivateApi")
|
||||
public final class SurfaceControl {
|
||||
|
||||
private static final Class<?> cls;
|
||||
private static final Class<?> CLASS;
|
||||
|
||||
static {
|
||||
try {
|
||||
cls = Class.forName("android.view.SurfaceControl");
|
||||
CLASS = Class.forName("android.view.SurfaceControl");
|
||||
} catch (ClassNotFoundException e) {
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
|
@ -22,7 +24,7 @@ public class SurfaceControl {
|
|||
|
||||
public static void openTransaction() {
|
||||
try {
|
||||
cls.getMethod("openTransaction").invoke(null);
|
||||
CLASS.getMethod("openTransaction").invoke(null);
|
||||
} catch (Exception e) {
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
|
@ -30,7 +32,7 @@ public class SurfaceControl {
|
|||
|
||||
public static void closeTransaction() {
|
||||
try {
|
||||
cls.getMethod("closeTransaction").invoke(null);
|
||||
CLASS.getMethod("closeTransaction").invoke(null);
|
||||
} catch (Exception e) {
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
|
@ -38,7 +40,7 @@ public class SurfaceControl {
|
|||
|
||||
public static void setDisplayProjection(IBinder displayToken, int orientation, Rect layerStackRect, Rect displayRect) {
|
||||
try {
|
||||
cls.getMethod("setDisplayProjection", IBinder.class, int.class, Rect.class, Rect.class)
|
||||
CLASS.getMethod("setDisplayProjection", IBinder.class, int.class, Rect.class, Rect.class)
|
||||
.invoke(null, displayToken, orientation, layerStackRect, displayRect);
|
||||
} catch (Exception e) {
|
||||
throw new AssertionError(e);
|
||||
|
@ -47,7 +49,7 @@ public class SurfaceControl {
|
|||
|
||||
public static void setDisplayLayerStack(IBinder displayToken, int layerStack) {
|
||||
try {
|
||||
cls.getMethod("setDisplayLayerStack", IBinder.class, int.class).invoke(null, displayToken, layerStack);
|
||||
CLASS.getMethod("setDisplayLayerStack", IBinder.class, int.class).invoke(null, displayToken, layerStack);
|
||||
} catch (Exception e) {
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
|
@ -55,7 +57,7 @@ public class SurfaceControl {
|
|||
|
||||
public static void setDisplaySurface(IBinder displayToken, Surface surface) {
|
||||
try {
|
||||
cls.getMethod("setDisplaySurface", IBinder.class, Surface.class).invoke(null, displayToken, surface);
|
||||
CLASS.getMethod("setDisplaySurface", IBinder.class, Surface.class).invoke(null, displayToken, surface);
|
||||
} catch (Exception e) {
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
|
@ -63,7 +65,7 @@ public class SurfaceControl {
|
|||
|
||||
public static IBinder createDisplay(String name, boolean secure) {
|
||||
try {
|
||||
return (IBinder) cls.getMethod("createDisplay", String.class, boolean.class).invoke(null, name, secure);
|
||||
return (IBinder) CLASS.getMethod("createDisplay", String.class, boolean.class).invoke(null, name, secure);
|
||||
} catch (Exception e) {
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
|
@ -71,7 +73,7 @@ public class SurfaceControl {
|
|||
|
||||
public static void destroyDisplay(IBinder displayToken) {
|
||||
try {
|
||||
cls.getMethod("destroyDisplay", IBinder.class).invoke(null, displayToken);
|
||||
CLASS.getMethod("destroyDisplay", IBinder.class).invoke(null, displayToken);
|
||||
} catch (Exception e) {
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@ package com.genymobile.scrcpy.wrappers;
|
|||
import android.os.IInterface;
|
||||
import android.view.IRotationWatcher;
|
||||
|
||||
public class WindowManager {
|
||||
public final class WindowManager {
|
||||
private final IInterface manager;
|
||||
|
||||
public WindowManager(IInterface manager) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue