Convert server to an Android project

To simplify the device server-side build, use gradle to create an APK,
even if we use it as a simple jar, by running its main() method.
This commit is contained in:
Romain Vimont 2018-01-29 17:06:44 +01:00
commit b67907e24e
36 changed files with 390 additions and 121 deletions

12
server/.gitignore vendored
View file

@ -1,4 +1,8 @@
*.class
*.jar
*.dex
/gen
*.iml
.gradle
/local.properties
/.idea/
.DS_Store
/build
/captures
.externalNativeBuild

View file

@ -1,92 +0,0 @@
.PHONY: jar push run clean compile compiletests test
SRC_DIR := src
GEN_DIR := gen
CLS_DIR := classes
CLS_DEX := classes.dex
TEST_SRC_DIR := tests
TEST_CLS_DIR := test_classes
TEST_LIBS := /usr/share/java/junit4.jar:/usr/share/java/hamcrest-core.jar
BUILD_TOOLS := $(ANDROID_HOME)/build-tools/26.0.2
AIDL := $(BUILD_TOOLS)/aidl
ifeq ($(OS),Windows_NT)
DX := $(BUILD_TOOLS)/dx.bat
else
DX := $(BUILD_TOOLS)/dx
endif
ANDROID_JAR := $(ANDROID_HOME)/platforms/android-26/android.jar
AIDL_SRC := android/view/IRotationWatcher.aidl
SRC := com/genymobile/scrcpy/ScrCpyServer.java \
com/genymobile/scrcpy/ControlEvent.java \
com/genymobile/scrcpy/ControlEventReader.java \
com/genymobile/scrcpy/DesktopConnection.java \
com/genymobile/scrcpy/Device.java \
com/genymobile/scrcpy/DisplayInfo.java \
com/genymobile/scrcpy/EventController.java \
com/genymobile/scrcpy/Ln.java \
com/genymobile/scrcpy/Options.java \
com/genymobile/scrcpy/Point.java \
com/genymobile/scrcpy/Position.java \
com/genymobile/scrcpy/ScreenInfo.java \
com/genymobile/scrcpy/ScreenStreamer.java \
com/genymobile/scrcpy/ScreenStreamerSession.java \
com/genymobile/scrcpy/Size.java \
com/genymobile/scrcpy/wrappers/DisplayManager.java \
com/genymobile/scrcpy/wrappers/InputManager.java \
com/genymobile/scrcpy/wrappers/ServiceManager.java \
com/genymobile/scrcpy/wrappers/WindowManager.java \
TEST_SRC := com/genymobile/scrcpy/ControlEventReaderTest.java \
# generate classnames from filepath
TEST_CLS := $(subst /,.,$(basename $(TEST_SRC)))
JAR := scrcpy-server.jar
MAIN := com.genymobile.scrcpy.ScrCpyServer
AIDL_GEN := $(AIDL_SRC:%.aidl=$(GEN_DIR)/%.java)
AIDL_CLS := $(AIDL_SRC:%.aidl=$(CLS_DIR)/%.class)
SRC_CLS := $(SRC:%.java=$(CLS_DIR)/%.class)
CLS := $(AIDL_CLS) $(SRC_CLS)
ALL_JAVA := $(AIDL_GEN) $(addprefix $(SRC_DIR)/,$(SRC))
ALL_TESTS := $(addprefix $(TEST_SRC_DIR)/,$(TEST_SRC))
jar: $(JAR)
$(AIDL_GEN): $(GEN_DIR)/%.java : $(SRC_DIR)/%.aidl
mkdir -p $(GEN_DIR)
"$(AIDL)" -o$(GEN_DIR) $(SRC_DIR)/$(AIDL_SRC)
compile: $(ALL_JAVA)
@mkdir -p "$(CLS_DIR)"
javac -source 1.7 -target 1.7 \
-cp "$(ANDROID_JAR)" \
-d "$(CLS_DIR)" -sourcepath $(SRC_DIR):$(GEN_DIR) \
$(ALL_JAVA)
$(JAR): $(ALL_JAVA)
# we cannot track easily class dependencies, so execute compile only when jar is outdated
+$(MAKE) compile
"$(DX)" --dex --output=$(CLS_DEX) $(CLS_DIR)
jar cvf $(JAR) classes.dex
push: jar
adb push $(JAR) /data/local/tmp/
run: push
adb shell "CLASSPATH=/data/local/tmp/$(JAR) app_process /system/bin $(MAIN)"
clean:
rm -rf $(CLS_DEX) $(CLS_DIR) $(GEN_DIR) $(JAR) $(TEST_CLS_DIR)
compiletests: compile $(ALL_TESTS)
@mkdir -p "$(TEST_CLS_DIR)"
javac -cp "$(TEST_LIBS):$(ANDROID_JAR):$(CLS_DIR)" -d "$(TEST_CLS_DIR)" -sourcepath "$(TEST_SRC_DIR)" $(ALL_TESTS)
test:
+$(MAKE) compiletests
java -cp "$(TEST_LIBS):$(ANDROID_JAR):$(CLS_DIR):$(TEST_CLS_DIR)" org.junit.runner.JUnitCore $(TEST_CLS)

26
server/build.gradle Normal file
View file

@ -0,0 +1,26 @@
apply plugin: 'com.android.application'
android {
compileSdkVersion 26
defaultConfig {
applicationId "com.genymobile.scrcpy"
minSdkVersion 21
targetSdkVersion 26
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.1'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
}

21
server/proguard-rules.pro vendored Normal file
View file

@ -0,0 +1,21 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile

View file

@ -0,0 +1,2 @@
<!-- not a real Android application, it is run by app_process manually -->
<manifest package="com.genymobile.scrcpy"/>

View file

@ -20,6 +20,6 @@ package android.view;
/**
* {@hide}
*/
oneway interface IRotationWatcher {
void onRotationChanged(int rotation);
interface IRotationWatcher {
oneway void onRotationChanged(int rotation);
}

View file

@ -40,6 +40,12 @@ public final class Device {
}
private ScreenInfo computeScreenInfo(int maximumSize) {
// Compute the video size and the padding of the content inside this video.
// Principle:
// - scale down the great side of the screen to maximumSize (if necessary);
// - scale down the other side so that the aspect ratio is preserved;
// - ceil this value to the next multiple of 8 (H.264 only accepts multiples of 8)
// - this may introduce black bands, so store the padding (typically a few pixels)
DisplayInfo displayInfo = serviceManager.getDisplayManager().getDisplayInfo();
boolean rotated = (displayInfo.getRotation() & 1) != 0;
Size deviceSize = displayInfo.getSize();

View file

@ -53,9 +53,7 @@ public class ScreenStreamerSession {
List<String> command = new ArrayList<>();
command.add("screenrecord");
command.add("--output-format=h264");
if (videoSize != null) {
command.add("--size=" + videoSize.getWidth() + "x" + videoSize.getHeight());
}
command.add("--size=" + videoSize.getWidth() + "x" + videoSize.getHeight());
command.add("-");
Process process = new ProcessBuilder(command).start();
process.getOutputStream().close();