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
28
config/android-checkstyle.gradle
Normal file
28
config/android-checkstyle.gradle
Normal file
|
@ -0,0 +1,28 @@
|
|||
apply plugin: 'checkstyle'
|
||||
check.dependsOn 'checkstyle'
|
||||
|
||||
checkstyle {
|
||||
toolVersion = '6.19'
|
||||
}
|
||||
|
||||
task checkstyle(type: Checkstyle) {
|
||||
description = "Check Java style with Checkstyle"
|
||||
configFile = rootProject.file("config/checkstyle/checkstyle.xml")
|
||||
source = javaSources()
|
||||
classpath = files()
|
||||
ignoreFailures = true
|
||||
}
|
||||
|
||||
def javaSources() {
|
||||
def files = []
|
||||
android.sourceSets.each { sourceSet ->
|
||||
sourceSet.java.each { javaSource ->
|
||||
javaSource.getSrcDirs().each {
|
||||
if (it.exists()) {
|
||||
files.add(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return files
|
||||
}
|
182
config/checkstyle/checkstyle.xml
Normal file
182
config/checkstyle/checkstyle.xml
Normal file
|
@ -0,0 +1,182 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE module PUBLIC
|
||||
"-//Puppy Crawl//DTD Check Configuration 1.3//EN"
|
||||
"http://www.puppycrawl.com/dtds/configuration_1_3.dtd">
|
||||
|
||||
<!-- This is a checkstyle configuration file. For descriptions of
|
||||
what the following rules do, please see the checkstyle configuration
|
||||
page at http://checkstyle.sourceforge.net/config.html -->
|
||||
|
||||
<module name="Checker">
|
||||
|
||||
<!-- Checks whether files end with a new line. -->
|
||||
<!-- See http://checkstyle.sf.net/config_misc.html#NewlineAtEndOfFile -->
|
||||
<module name="NewlineAtEndOfFile" />
|
||||
|
||||
<!-- Checks that property files contain the same keys. -->
|
||||
<!-- See http://checkstyle.sf.net/config_misc.html#Translation -->
|
||||
<module name="Translation" />
|
||||
|
||||
<!-- Checks for Size Violations. -->
|
||||
<!-- See http://checkstyle.sf.net/config_sizes.html -->
|
||||
<module name="FileLength" />
|
||||
|
||||
<!-- Checks for whitespace -->
|
||||
<!-- See http://checkstyle.sf.net/config_whitespace.html -->
|
||||
<module name="FileTabCharacter" />
|
||||
|
||||
<!-- Miscellaneous other checks. -->
|
||||
<!-- See http://checkstyle.sf.net/config_misc.html -->
|
||||
<module name="RegexpSingleline">
|
||||
<property name="format" value="\s+$" />
|
||||
<property name="minimum" value="0" />
|
||||
<property name="maximum" value="0" />
|
||||
<property name="message" value="Line has trailing spaces." />
|
||||
<property name="severity" value="info" />
|
||||
</module>
|
||||
|
||||
<module name="SuppressWarningsFilter"/>
|
||||
|
||||
<module name="TreeWalker">
|
||||
|
||||
<!-- Checks for Naming Conventions. -->
|
||||
<!-- See http://checkstyle.sf.net/config_naming.html -->
|
||||
<module name="ConstantName" />
|
||||
<module name="LocalFinalVariableName" />
|
||||
<module name="LocalVariableName" />
|
||||
<module name="MemberName" />
|
||||
<module name="MethodName" />
|
||||
<module name="PackageName" />
|
||||
<module name="ParameterName" />
|
||||
<module name="StaticVariableName" />
|
||||
<module name="TypeName" />
|
||||
|
||||
<module name="SuppressWarningsHolder"/>
|
||||
|
||||
<!-- Checks for imports -->
|
||||
<!-- See http://checkstyle.sf.net/config_import.html -->
|
||||
<module name="AvoidStarImport">
|
||||
<property name="allowStaticMemberImports" value="true" />
|
||||
</module>
|
||||
<module name="IllegalImport" />
|
||||
<!-- defaults to sun.* packages -->
|
||||
<module name="RedundantImport" />
|
||||
<module name="UnusedImports" />
|
||||
<module name="CustomImportOrder">
|
||||
<property name="thirdPartyPackageRegExp" value=".*"/>
|
||||
<property name="specialImportsRegExp" value="com.genymobile"/>
|
||||
<property name="separateLineBetweenGroups" value="true"/>
|
||||
<property name="customImportOrderRules" value="SPECIAL_IMPORTS###THIRD_PARTY_PACKAGE###STANDARD_JAVA_PACKAGE###STATIC"/>
|
||||
</module>
|
||||
|
||||
|
||||
<!-- Checks for Size Violations. -->
|
||||
<!-- See http://checkstyle.sf.net/config_sizes.html -->
|
||||
<module name="LineLength">
|
||||
<!-- what is a good max value? -->
|
||||
<property name="max" value="150" />
|
||||
<!-- ignore lines like "$File: //depot/... $" -->
|
||||
<property name="ignorePattern" value="\$File.*\$" />
|
||||
<property name="severity" value="info" />
|
||||
</module>
|
||||
<module name="MethodLength" />
|
||||
<module name="ParameterNumber">
|
||||
<property name="ignoreOverriddenMethods" value="true"/>
|
||||
</module>
|
||||
|
||||
|
||||
<!-- Checks for whitespace -->
|
||||
<!-- See http://checkstyle.sf.net/config_whitespace.html -->
|
||||
<module name="EmptyForIteratorPad" />
|
||||
<module name="GenericWhitespace" />
|
||||
<module name="MethodParamPad" />
|
||||
<module name="NoWhitespaceAfter" />
|
||||
<module name="NoWhitespaceBefore" />
|
||||
<module name="OperatorWrap" />
|
||||
<module name="ParenPad" />
|
||||
<module name="TypecastParenPad" />
|
||||
<module name="WhitespaceAfter" />
|
||||
<module name="WhitespaceAround" />
|
||||
|
||||
<!-- Modifier Checks -->
|
||||
<!-- See http://checkstyle.sf.net/config_modifiers.html -->
|
||||
<module name="ModifierOrder" />
|
||||
<module name="RedundantModifier" />
|
||||
|
||||
|
||||
<!-- Checks for blocks. You know, those {}'s -->
|
||||
<!-- See http://checkstyle.sf.net/config_blocks.html -->
|
||||
<module name="AvoidNestedBlocks" />
|
||||
<module name="EmptyBlock">
|
||||
<property name="option" value="text" />
|
||||
</module>
|
||||
<module name="LeftCurly" />
|
||||
<module name="NeedBraces" />
|
||||
<module name="RightCurly" />
|
||||
|
||||
|
||||
<!-- Checks for common coding problems -->
|
||||
<!-- See http://checkstyle.sf.net/config_coding.html -->
|
||||
<!-- <module name="AvoidInlineConditionals"/> -->
|
||||
<module name="EmptyStatement" />
|
||||
<module name="EqualsHashCode" />
|
||||
<module name="HiddenField">
|
||||
<property name="tokens" value="VARIABLE_DEF" />
|
||||
<!-- only check variables not parameters -->
|
||||
<property name="ignoreConstructorParameter" value="true" />
|
||||
<property name="ignoreSetter" value="true" />
|
||||
<property name="severity" value="warning" />
|
||||
</module>
|
||||
<module name="IllegalInstantiation" />
|
||||
<module name="InnerAssignment" />
|
||||
<module name="MagicNumber">
|
||||
<property name="severity" value="info" />
|
||||
<property name="ignoreHashCodeMethod" value="true" />
|
||||
<property name="ignoreAnnotation" value="true" />
|
||||
</module>
|
||||
<module name="MissingSwitchDefault" />
|
||||
<module name="SimplifyBooleanExpression" />
|
||||
<module name="SimplifyBooleanReturn" />
|
||||
|
||||
<!-- Checks for class design -->
|
||||
<!-- See http://checkstyle.sf.net/config_design.html -->
|
||||
<!-- <module name="DesignForExtension"/> -->
|
||||
<module name="FinalClass" />
|
||||
<module name="HideUtilityClassConstructor" />
|
||||
<module name="InterfaceIsType" />
|
||||
<module name="VisibilityModifier" />
|
||||
|
||||
|
||||
<!-- Miscellaneous other checks. -->
|
||||
<!-- See http://checkstyle.sf.net/config_misc.html -->
|
||||
<module name="ArrayTypeStyle" />
|
||||
<!-- <module name="FinalParameters"/> -->
|
||||
<module name="TodoComment">
|
||||
<property name="format" value="TODO" />
|
||||
<property name="severity" value="info" />
|
||||
</module>
|
||||
<module name="UpperEll" />
|
||||
|
||||
<module name="FileContentsHolder" />
|
||||
<!-- Required by comment suppression filters -->
|
||||
|
||||
</module>
|
||||
|
||||
<module name="SuppressionFilter">
|
||||
<!--<property name="file" value="team-props/checkstyle/checkstyle-suppressions.xml" />-->
|
||||
</module>
|
||||
|
||||
<!-- Enable suppression comments -->
|
||||
<module name="SuppressionCommentFilter">
|
||||
<property name="offCommentFormat" value="CHECKSTYLE IGNORE\s+(\S+)" />
|
||||
<property name="onCommentFormat" value="CHECKSTYLE END IGNORE\s+(\S+)" />
|
||||
<property name="checkFormat" value="$1" />
|
||||
</module>
|
||||
<module name="SuppressWithNearbyCommentFilter">
|
||||
<!-- Syntax is "SUPPRESS CHECKSTYLE name" -->
|
||||
<property name="commentFormat" value="SUPPRESS CHECKSTYLE (\w+)" />
|
||||
<property name="checkFormat" value="$1" />
|
||||
<property name="influenceFormat" value="1" />
|
||||
</module>
|
||||
|
||||
</module>
|
|
@ -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…
Reference in a new issue