Skip to content

Commit 84b94b4

Browse files
committed
增加server代码,android studio可直接编译
1 parent dfadeeb commit 84b94b4

27 files changed

+1965
-0
lines changed

server/build.gradle

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
apply plugin: 'com.android.application'
2+
3+
buildscript {
4+
5+
repositories {
6+
google()
7+
jcenter()
8+
}
9+
dependencies {
10+
classpath 'com.android.tools.build:gradle:3.1.1'
11+
12+
// NOTE: Do not place your application dependencies here; they belong
13+
// in the individual module build.gradle files
14+
}
15+
}
16+
17+
allprojects {
18+
repositories {
19+
google()
20+
jcenter()
21+
}
22+
}
23+
24+
android {
25+
compileSdkVersion 27
26+
defaultConfig {
27+
applicationId "com.genymobile.scrcpy"
28+
minSdkVersion 21
29+
targetSdkVersion 27
30+
versionCode 5
31+
versionName "1.4"
32+
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
33+
}
34+
buildTypes {
35+
release {
36+
minifyEnabled false
37+
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
38+
}
39+
}
40+
}
41+
42+
dependencies {
43+
implementation fileTree(dir: 'libs', include: ['*.jar'])
44+
testImplementation 'junit:junit:4.12'
45+
}
46+
47+
apply from: "$project.rootDir/config/android-checkstyle.gradle"
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
apply plugin: 'checkstyle'
2+
check.dependsOn 'checkstyle'
3+
4+
checkstyle {
5+
toolVersion = '6.19'
6+
}
7+
8+
task checkstyle(type: Checkstyle) {
9+
description = "Check Java style with Checkstyle"
10+
configFile = rootProject.file("config/checkstyle/checkstyle.xml")
11+
source = javaSources()
12+
classpath = files()
13+
ignoreFailures = true
14+
}
15+
16+
def javaSources() {
17+
def files = []
18+
android.sourceSets.each { sourceSet ->
19+
sourceSet.java.each { javaSource ->
20+
javaSource.getSrcDirs().each {
21+
if (it.exists()) {
22+
files.add(it)
23+
}
24+
}
25+
}
26+
}
27+
return files
28+
}

server/proguard-rules.pro

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# Add project specific ProGuard rules here.
2+
# You can control the set of applied configuration files using the
3+
# proguardFiles setting in build.gradle.
4+
#
5+
# For more details, see
6+
# http://developer.android.com/guide/developing/tools/proguard.html
7+
8+
# If your project uses WebView with JS, uncomment the following
9+
# and specify the fully qualified class name to the JavaScript interface
10+
# class:
11+
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12+
# public *;
13+
#}
14+
15+
# Uncomment this to preserve the line number information for
16+
# debugging stack traces.
17+
#-keepattributes SourceFile,LineNumberTable
18+
19+
# If you keep the line number information, uncomment this to
20+
# hide the original source file name.
21+
#-renamesourcefileattribute SourceFile

server/src/main/AndroidManifest.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
<!-- not a real Android application, it is run by app_process manually -->
2+
<manifest package="com.genymobile.scrcpy"/>
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/* //device/java/android/android/hardware/ISensorListener.aidl
2+
**
3+
** Copyright 2008, The Android Open Source Project
4+
**
5+
** Licensed under the Apache License, Version 2.0 (the "License");
6+
** you may not use this file except in compliance with the License.
7+
** You may obtain a copy of the License at
8+
**
9+
** http://www.apache.org/licenses/LICENSE-2.0
10+
**
11+
** Unless required by applicable law or agreed to in writing, software
12+
** distributed under the License is distributed on an "AS IS" BASIS,
13+
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
** See the License for the specific language governing permissions and
15+
** limitations under the License.
16+
*/
17+
18+
package android.view;
19+
20+
/**
21+
* {@hide}
22+
*/
23+
interface IRotationWatcher {
24+
oneway void onRotationChanged(int rotation);
25+
}
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
package com.genymobile.scrcpy;
2+
3+
/**
4+
* Union of all supported event types, identified by their {@code type}.
5+
*/
6+
public final class ControlEvent {
7+
8+
public static final int TYPE_KEYCODE = 0;
9+
public static final int TYPE_TEXT = 1;
10+
public static final int TYPE_MOUSE = 2;
11+
public static final int TYPE_SCROLL = 3;
12+
public static final int TYPE_COMMAND = 4;
13+
14+
public static final int COMMAND_BACK_OR_SCREEN_ON = 0;
15+
16+
private int type;
17+
private String text;
18+
private int metaState; // KeyEvent.META_*
19+
private int action; // KeyEvent.ACTION_* or MotionEvent.ACTION_* or COMMAND_*
20+
private int keycode; // KeyEvent.KEYCODE_*
21+
private int buttons; // MotionEvent.BUTTON_*
22+
private Position position;
23+
private int hScroll;
24+
private int vScroll;
25+
26+
private ControlEvent() {
27+
}
28+
29+
public static ControlEvent createKeycodeControlEvent(int action, int keycode, int metaState) {
30+
ControlEvent event = new ControlEvent();
31+
event.type = TYPE_KEYCODE;
32+
event.action = action;
33+
event.keycode = keycode;
34+
event.metaState = metaState;
35+
return event;
36+
}
37+
38+
public static ControlEvent createTextControlEvent(String text) {
39+
ControlEvent event = new ControlEvent();
40+
event.type = TYPE_TEXT;
41+
event.text = text;
42+
return event;
43+
}
44+
45+
public static ControlEvent createMotionControlEvent(int action, int buttons, Position position) {
46+
ControlEvent event = new ControlEvent();
47+
event.type = TYPE_MOUSE;
48+
event.action = action;
49+
event.buttons = buttons;
50+
event.position = position;
51+
return event;
52+
}
53+
54+
public static ControlEvent createScrollControlEvent(Position position, int hScroll, int vScroll) {
55+
ControlEvent event = new ControlEvent();
56+
event.type = TYPE_SCROLL;
57+
event.position = position;
58+
event.hScroll = hScroll;
59+
event.vScroll = vScroll;
60+
return event;
61+
}
62+
63+
public static ControlEvent createCommandControlEvent(int action) {
64+
ControlEvent event = new ControlEvent();
65+
event.type = TYPE_COMMAND;
66+
event.action = action;
67+
return event;
68+
}
69+
70+
public int getType() {
71+
return type;
72+
}
73+
74+
public String getText() {
75+
return text;
76+
}
77+
78+
public int getMetaState() {
79+
return metaState;
80+
}
81+
82+
public int getAction() {
83+
return action;
84+
}
85+
86+
public int getKeycode() {
87+
return keycode;
88+
}
89+
90+
public int getButtons() {
91+
return buttons;
92+
}
93+
94+
public Position getPosition() {
95+
return position;
96+
}
97+
98+
public int getHScroll() {
99+
return hScroll;
100+
}
101+
102+
public int getVScroll() {
103+
return vScroll;
104+
}
105+
}
Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
package com.genymobile.scrcpy;
2+
3+
import java.io.EOFException;
4+
import java.io.IOException;
5+
import java.io.InputStream;
6+
import java.nio.ByteBuffer;
7+
import java.nio.charset.StandardCharsets;
8+
9+
public class ControlEventReader {
10+
11+
private static final int KEYCODE_PAYLOAD_LENGTH = 9;
12+
private static final int MOUSE_PAYLOAD_LENGTH = 13;
13+
private static final int SCROLL_PAYLOAD_LENGTH = 16;
14+
private static final int COMMAND_PAYLOAD_LENGTH = 1;
15+
16+
public static final int TEXT_MAX_LENGTH = 300;
17+
private static final int RAW_BUFFER_SIZE = 1024;
18+
19+
private final byte[] rawBuffer = new byte[RAW_BUFFER_SIZE];
20+
private final ByteBuffer buffer = ByteBuffer.wrap(rawBuffer);
21+
private final byte[] textBuffer = new byte[TEXT_MAX_LENGTH];
22+
23+
public ControlEventReader() {
24+
// invariant: the buffer is always in "get" mode
25+
buffer.limit(0);
26+
}
27+
28+
public boolean isFull() {
29+
return buffer.remaining() == rawBuffer.length;
30+
}
31+
32+
public void readFrom(InputStream input) throws IOException {
33+
if (isFull()) {
34+
throw new IllegalStateException("Buffer full, call next() to consume");
35+
}
36+
buffer.compact();
37+
int head = buffer.position();
38+
int r = input.read(rawBuffer, head, rawBuffer.length - head);
39+
if (r == -1) {
40+
throw new EOFException("Event controller socket closed");
41+
}
42+
buffer.position(head + r);
43+
buffer.flip();
44+
}
45+
46+
public ControlEvent next() {
47+
if (!buffer.hasRemaining()) {
48+
return null;
49+
}
50+
int savedPosition = buffer.position();
51+
52+
int type = buffer.get();
53+
ControlEvent controlEvent;
54+
switch (type) {
55+
case ControlEvent.TYPE_KEYCODE:
56+
controlEvent = parseKeycodeControlEvent();
57+
break;
58+
case ControlEvent.TYPE_TEXT:
59+
controlEvent = parseTextControlEvent();
60+
break;
61+
case ControlEvent.TYPE_MOUSE:
62+
controlEvent = parseMouseControlEvent();
63+
break;
64+
case ControlEvent.TYPE_SCROLL:
65+
controlEvent = parseScrollControlEvent();
66+
break;
67+
case ControlEvent.TYPE_COMMAND:
68+
controlEvent = parseCommandControlEvent();
69+
break;
70+
default:
71+
Ln.w("Unknown event type: " + type);
72+
controlEvent = null;
73+
break;
74+
}
75+
76+
if (controlEvent == null) {
77+
// failure, reset savedPosition
78+
buffer.position(savedPosition);
79+
}
80+
return controlEvent;
81+
}
82+
83+
private ControlEvent parseKeycodeControlEvent() {
84+
if (buffer.remaining() < KEYCODE_PAYLOAD_LENGTH) {
85+
return null;
86+
}
87+
int action = toUnsigned(buffer.get());
88+
int keycode = buffer.getInt();
89+
int metaState = buffer.getInt();
90+
return ControlEvent.createKeycodeControlEvent(action, keycode, metaState);
91+
}
92+
93+
private ControlEvent parseTextControlEvent() {
94+
if (buffer.remaining() < 1) {
95+
return null;
96+
}
97+
int len = toUnsigned(buffer.getShort());
98+
if (buffer.remaining() < len) {
99+
return null;
100+
}
101+
buffer.get(textBuffer, 0, len);
102+
String text = new String(textBuffer, 0, len, StandardCharsets.UTF_8);
103+
return ControlEvent.createTextControlEvent(text);
104+
}
105+
106+
private ControlEvent parseMouseControlEvent() {
107+
if (buffer.remaining() < MOUSE_PAYLOAD_LENGTH) {
108+
return null;
109+
}
110+
int action = toUnsigned(buffer.get());
111+
int buttons = buffer.getInt();
112+
Position position = readPosition(buffer);
113+
return ControlEvent.createMotionControlEvent(action, buttons, position);
114+
}
115+
116+
private ControlEvent parseScrollControlEvent() {
117+
if (buffer.remaining() < SCROLL_PAYLOAD_LENGTH) {
118+
return null;
119+
}
120+
Position position = readPosition(buffer);
121+
int hScroll = buffer.getInt();
122+
int vScroll = buffer.getInt();
123+
return ControlEvent.createScrollControlEvent(position, hScroll, vScroll);
124+
}
125+
126+
private ControlEvent parseCommandControlEvent() {
127+
if (buffer.remaining() < COMMAND_PAYLOAD_LENGTH) {
128+
return null;
129+
}
130+
int action = toUnsigned(buffer.get());
131+
return ControlEvent.createCommandControlEvent(action);
132+
}
133+
134+
private static Position readPosition(ByteBuffer buffer) {
135+
int x = toUnsigned(buffer.getShort());
136+
int y = toUnsigned(buffer.getShort());
137+
int screenWidth = toUnsigned(buffer.getShort());
138+
int screenHeight = toUnsigned(buffer.getShort());
139+
return new Position(x, y, screenWidth, screenHeight);
140+
}
141+
142+
@SuppressWarnings("checkstyle:MagicNumber")
143+
private static int toUnsigned(short value) {
144+
return value & 0xffff;
145+
}
146+
147+
@SuppressWarnings("checkstyle:MagicNumber")
148+
private static int toUnsigned(byte value) {
149+
return value & 0xff;
150+
}
151+
}

0 commit comments

Comments
 (0)