src/com/acouchi/Acouchi.java in acouchi-0.0.2 vs src/com/acouchi/Acouchi.java in acouchi-0.0.3

- old
+ new

@@ -9,18 +9,26 @@ import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; import android.app.Instrumentation; import android.app.Activity; +import android.widget.TextView; +import android.view.View; import java.lang.reflect.Method; +import java.lang.reflect.InvocationTargetException; import org.json.JSONArray; import org.json.JSONObject; import org.json.JSONException; import java.util.ArrayList; +import java.util.Map; +import java.util.HashMap; +import java.util.Collection; import java.io.PrintWriter; import java.io.StringWriter; import java.io.Writer; +import com.google.gson.Gson; +import android.widget.Button; public class Acouchi extends NanoHTTPD { private Solo solo; private boolean serverRunning = true; @@ -62,54 +70,186 @@ return new NanoHTTPD.Response(HTTP_OK, MIME_HTML, ""); } else if (uri.startsWith("/execute_method")) { String methodName = uri.replace("/execute_method/", ""); - return ExecuteMethod(methodName, params.getProperty("parameters")); + try { + return ExecuteMethod(methodName, params.getProperty("parameters")); + } catch (Throwable throwable) { + return showException(throwable); + } } return new NanoHTTPD.Response(HTTP_OK, MIME_HTML, "Acouchi"); } - private NanoHTTPD.Response ExecuteMethod(String methodName, String json) + private NanoHTTPD.Response ExecuteMethod(String methodName, String json) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, JSONException, ClassNotFoundException { - try { - JSONArray jsonArray = new JSONArray(json); + if (methodName.equals("getCurrentContent")) + return new NanoHTTPD.Response(HTTP_OK, MIME_HTML, getCurrentContentAsJson()); + + JSONArray jsonArray = new JSONArray(json); + + if (methodName.equals("clickOnText")) { + String text = jsonArray.getJSONObject(0).getString("value"); + int match = jsonArray.getJSONObject(1).getInt("value"); + boolean scroll = jsonArray.getJSONObject(2).getBoolean("value"); + try { + solo.clickOnText(text, match, scroll); + } catch (Exception exception) { + return showException(exception); + } + return displayMethodResultAsJson(methodName, null); + } else if (methodName.equals("scrollUpList")) { + int index = jsonArray.getJSONObject(0).getInt("value"); + try { + solo.scrollUpList(index); + } catch (Exception exception) { + return showException(exception); + } + return displayMethodResultAsJson(methodName, null); + } else if (methodName.equals("scrollDownList")) { + int index = jsonArray.getJSONObject(0).getInt("value"); + try { + solo.scrollDownList(index); + } catch (Exception exception) { + return showException(exception); + } + return displayMethodResultAsJson(methodName, null); + } else { Class[] parameterTypes = new Class[jsonArray.length()]; Object[] parameters = new Object[jsonArray.length()]; for (int i = 0; i < jsonArray.length(); i++) { JSONObject jsonObject = jsonArray.getJSONObject(i); parameterTypes[i] = getClassType(jsonObject.getString("type")); parameters[i] = getConvertedValue(jsonObject.getString("type"), jsonObject.getString("value")); } + Object result = executeMethodOnSomeClass(methodName, parameterTypes, parameters); + return displayMethodResultAsJson(methodName, result); + } + } + private class MethodExecutor + { + private Solo solo; + private Object[] parameters; + + public MethodExecutor(Solo solo, Object[] parameters) + { + this.solo = solo; + this.parameters = parameters; + } + } + + private Object executeMethodOnSomeClass(String methodName, Class[] parameterTypes, Object[] parameters) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException + { + try { Method method = solo.getClass().getMethod(methodName, parameterTypes); - return displayMethodResultAsJson(method.invoke(solo, parameters)); + return method.invoke(solo, parameters); } catch (Exception exception) { - return showException(exception); } + + Method method = this.getClass().getMethod(methodName, parameterTypes); + return method.invoke(this, parameters); } - private NanoHTTPD.Response displayMethodResultAsJson(Object result) + private NanoHTTPD.Response displayMethodResultAsJson(String methodName, Object result) { try { JSONObject object = new JSONObject(); - if (result == null) { - object.put("emptyResult", true); - } else { + if (methodName.equals("getCurrentButtons")) + return new NanoHTTPD.Response(HTTP_OK, MIME_HTML, getButtonsAsJson((ArrayList<Button>)result)); + + if (methodName.equals("getViews")) + return new NanoHTTPD.Response(HTTP_OK, MIME_HTML, getViewsAsJson((ArrayList<View>)result)); + + if (methodName.equals("getView")) + return new NanoHTTPD.Response(HTTP_OK, MIME_HTML, getViewAsJson((View)result)); + + if (result != null) object.put("result", result); - } return new NanoHTTPD.Response(HTTP_OK, MIME_HTML, object.toString()); } catch (JSONException e) { return showException(e); } } + public void clickOnViewById(int id) + { + solo.clickOnView(solo.getView(id)); + } + + private String getViewsAsJson(ArrayList<View> views) + { + ArrayList<JsonView> jsonViews = new ArrayList<JsonView>(); + for(int index = 0; index < views.size(); index++) + jsonViews.add(new JsonView(views.get(index))); + JsonResult result = new JsonResult(jsonViews); + return new Gson().toJson(result); + } + + private String getViewAsJson(View view) + { + JsonResult result = new JsonResult(new JsonView(view)); + return new Gson().toJson(result); + } + + private class JsonView + { + private int id; + private String className; + + public JsonView(View view) + { + id = view.getId(); + className = view.getClass().toString(); + } + } + + private String getButtonsAsJson(ArrayList<Button> buttons) + { + ArrayList<JsonButton> jsonButtons = new ArrayList<JsonButton>(); + for(int index = 0; index < buttons.size(); index++) + jsonButtons.add(new JsonButton(buttons.get(index))); + JsonResult result = new JsonResult(jsonButtons); + return new Gson().toJson(result); + } + + private String getCurrentContentAsJson() + { + ArrayList<TextView> currentTextViews = solo.getCurrentTextViews(null); + ArrayList<String> content = new ArrayList<String>(); + for (TextView textView: currentTextViews) + content.add(textView.getText().toString()); + JsonResult result = new JsonResult(content); + return new Gson().toJson(result); + } + + private class JsonResult + { + private Object result; + + public JsonResult(Object result) + { + this.result = result; + } + } + + private class JsonButton + { + private String text; + + public JsonButton(Button button) + { + text = button.getText().toString(); + } + } + private Class getClassType(String name) throws java.lang.ClassNotFoundException { if (name.equals("int")) return int.class; if (name.equals("long")) return long.class; if (name.equals("double")) return double.class; @@ -128,17 +268,13 @@ if (name.equals("java.lang.Double")) return Double.parseDouble(value); if (name.equals("java.lang.Boolean")) return Boolean.parseBoolean(value); return value; } - private NanoHTTPD.Response showException(Exception exception) + private NanoHTTPD.Response showException(Throwable throwable) { - return new NanoHTTPD.Response(HTTP_OK, MIME_HTML, "exception: " + exception.toString() + "\n" + getStackTrace(exception)); - } - - private static String getStackTrace(Throwable aThrowable) { final Writer result = new StringWriter(); final PrintWriter printWriter = new PrintWriter(result); - aThrowable.printStackTrace(printWriter); - return result.toString(); + throwable.printStackTrace(printWriter); + return new NanoHTTPD.Response(HTTP_OK, MIME_HTML, "error: " + throwable.getMessage() + "\n" + result.toString()); } }