Skip to content

Commit bc33fd6

Browse files
committed
Merge branch 'develop'
2 parents 8834fd1 + 46c6d5e commit bc33fd6

File tree

3 files changed

+541
-222
lines changed

3 files changed

+541
-222
lines changed
Lines changed: 61 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,55 +1,73 @@
11
package com.github.uiautomatorstub;
22

3-
import java.io.ByteArrayInputStream;
4-
import java.io.ByteArrayOutputStream;
5-
import java.io.IOException;
6-
import java.nio.charset.Charset;
7-
import java.nio.charset.CharsetDecoder;
8-
import java.nio.charset.CharsetEncoder;
3+
import java.io.*;
94
import java.util.HashMap;
105
import java.util.Map;
116

7+
import android.os.Build;
8+
import com.android.uiautomator.core.UiDevice;
129
import com.googlecode.jsonrpc4j.JsonRpcServer;
1310

1411
import fi.iki.elonen.NanoHTTPD;
1512

1613
public class AutomatorHttpServer extends NanoHTTPD {
1714

18-
public AutomatorHttpServer(int port) {
19-
super(port);
20-
}
21-
22-
private static Charset charset = Charset.forName("UTF-8");
23-
private static CharsetEncoder encoder = charset.newEncoder();
24-
private static CharsetDecoder decoder = charset.newDecoder();
25-
26-
private Map<String, JsonRpcServer> router = new HashMap<String, JsonRpcServer>();
27-
28-
public void route(String uri, JsonRpcServer rpc) {
29-
router.put(uri, rpc);
30-
}
31-
32-
@Override
33-
public Response serve(String uri, Method method,
34-
Map<String, String> headers, Map<String, String> parms,
35-
Map<String, String> files) {
36-
Log.d(String.format("URI: %s, Method: %s, Header: %s, parms, %s, files: %s", uri, method, headers, parms, files));
37-
38-
if ("/stop".equals(uri)) {
39-
stop();
40-
return new Response("Server stopped!!!");
41-
}
42-
else if (router.containsKey(uri)) {
43-
JsonRpcServer jsonRpcServer = router.get(uri);
44-
ByteArrayInputStream is = new ByteArrayInputStream(parms.get("NanoHttpd.QUERY_STRING").getBytes());
45-
ByteArrayOutputStream os = new ByteArrayOutputStream();
46-
try {
47-
jsonRpcServer.handle(is, os);
48-
return new Response(Response.Status.OK, "application/json", new ByteArrayInputStream((os.toByteArray())));
49-
} catch (IOException e) {
50-
return new Response(Response.Status.INTERNAL_ERROR, MIME_PLAINTEXT, "Internal Server Error!!!");
51-
}
52-
} else
53-
return new Response(Response.Status.NOT_FOUND, MIME_PLAINTEXT, "Not Found!!!");
54-
}
15+
public AutomatorHttpServer(int port) {
16+
super(port);
17+
}
18+
19+
private Map<String, JsonRpcServer> router = new HashMap<String, JsonRpcServer>();
20+
21+
public void route(String uri, JsonRpcServer rpc) {
22+
router.put(uri, rpc);
23+
}
24+
25+
@Override
26+
public Response serve(String uri, Method method,
27+
Map<String, String> headers, Map<String, String> params,
28+
Map<String, String> files) {
29+
Log.d(String.format("URI: %s, Method: %s, Header: %s, params, %s, files: %s", uri, method, headers, params, files));
30+
31+
if ("/stop".equals(uri)) {
32+
stop();
33+
return new Response("Server stopped!!!");
34+
} else if ("/api/screenshot".equals(uri)) {
35+
if (Build.VERSION.SDK_INT < 17)
36+
return new Response(Response.Status.INTERNAL_ERROR, MIME_PLAINTEXT, "API level less than 17.");
37+
File f = new File(AutomatorServiceImpl.STORAGE_PATH, "screenshot.png");
38+
float scale = 1.0f;
39+
if (params.containsKey("scale")) {
40+
try {
41+
scale = Float.parseFloat(params.get("scale"));
42+
} catch (NumberFormatException e) {
43+
}
44+
}
45+
int quality = 100;
46+
if (params.containsKey("quality")) {
47+
try {
48+
quality = Integer.parseInt(params.get("quality"));
49+
} catch (NumberFormatException e) {
50+
}
51+
}
52+
UiDevice.getInstance().takeScreenshot(f, scale, quality);
53+
try {
54+
return new Response(Response.Status.OK, "image/png", new FileInputStream(f));
55+
} catch (FileNotFoundException e) {
56+
Log.e(e.getMessage());
57+
return new Response(Response.Status.INTERNAL_ERROR, MIME_PLAINTEXT, "Internal Server Error!!!");
58+
}
59+
} else if (router.containsKey(uri)) {
60+
JsonRpcServer jsonRpcServer = router.get(uri);
61+
ByteArrayInputStream is = new ByteArrayInputStream(params.get("NanoHttpd.QUERY_STRING").getBytes());
62+
ByteArrayOutputStream os = new ByteArrayOutputStream();
63+
try {
64+
jsonRpcServer.handle(is, os);
65+
return new Response(Response.Status.OK, "application/json", new ByteArrayInputStream(os.toByteArray()));
66+
} catch (IOException e) {
67+
return new Response(Response.Status.INTERNAL_ERROR, MIME_PLAINTEXT, "Internal Server Error!!!");
68+
}
69+
} else
70+
return new Response(Response.Status.NOT_FOUND, MIME_PLAINTEXT, "Not Found!!!");
71+
}
72+
5573
}

src/com/github/uiautomatorstub/AutomatorServiceImpl.java

Lines changed: 39 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33
import android.os.Build;
44
import android.os.Environment;
55
import android.os.RemoteException;
6-
import java.io.File;
6+
7+
import java.io.*;
78
import java.lang.reflect.InvocationTargetException;
89
import java.util.*;
910
import java.util.concurrent.ConcurrentHashMap;
@@ -16,7 +17,7 @@
1617

1718
public class AutomatorServiceImpl implements AutomatorService {
1819

19-
final static String STORAGE_PATH = "/data/local/tmp/";
20+
final public static String STORAGE_PATH = "/data/local/tmp/";
2021
private final HashSet<String> watchers = new HashSet<String>();
2122
private final ConcurrentHashMap<String, UiObject> uiObjects = new ConcurrentHashMap<String, UiObject>();
2223

@@ -142,14 +143,44 @@ public String dumpWindowHierarchy(boolean compressed, String filename) {
142143
File parent = new File(Environment.getDataDirectory(), "local/tmp"); // Environment.getDataDirectory() return /data/local/tmp in android 4.3 but not expected /data
143144
if (!parent.exists())
144145
parent.mkdirs();
146+
boolean return_value = false;
147+
if (filename == null || filename == "") {
148+
filename = "dump.xml";
149+
return_value = true;
150+
}
145151
File dumpFile = new File(parent, filename).getAbsoluteFile();
146152
UiDevice.getInstance().dumpWindowHierarchy(filename);
147-
File f = new File(STORAGE_PATH, filename); // It should be this...
148-
if (f.exists())
149-
return f.getAbsolutePath();
150-
else if (dumpFile.exists())
151-
return dumpFile.getAbsolutePath();
152-
else
153+
File f = new File(STORAGE_PATH, filename); // It should be this one, but in Android4.3, it is "/data/local/tmp/local/tmp"......
154+
if (!f.exists()) f = dumpFile;
155+
if (f.exists()) {
156+
if (return_value) {
157+
BufferedReader reader = null;
158+
try {
159+
StringBuilder sb = new StringBuilder();
160+
reader = new BufferedReader(new FileReader(f));
161+
char[] buffer = new char[4096];
162+
int len = 0;
163+
while ((len = reader.read(buffer)) != -1) {
164+
sb.append(new String(buffer, 0, len));
165+
}
166+
reader.close();
167+
reader = null;
168+
return sb.toString();
169+
} catch (IOException e) {
170+
Log.e(e.toString());
171+
} finally {
172+
if (reader != null) {
173+
try {
174+
reader.close();
175+
reader = null;
176+
} catch (IOException e1) {
177+
}
178+
}
179+
}
180+
return null;
181+
} else
182+
return f.getAbsolutePath();
183+
} else
153184
return null;
154185
}
155186

0 commit comments

Comments
 (0)