Skip to content

Instantly share code, notes, and snippets.

@AndrewVos
Created October 11, 2012 09:59
Show Gist options
  • Save AndrewVos/3871362 to your computer and use it in GitHub Desktop.
Save AndrewVos/3871362 to your computer and use it in GitHub Desktop.
package com.acouchi;
import com.jayway.android.robotium.solo.Solo;
import java.util.Properties;
import java.io.File;
import java.io.IOException;
import java.util.concurrent.locks.Condition;
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;
private Lock lock = new ReentrantLock();
private Condition endedCondition = lock.newCondition();
public Acouchi(Solo solo) throws IOException
{
super(7103, new File("."));
this.solo = solo;
}
public void WaitUntilServerKilled() throws InterruptedException
{
lock.lock();
try {
while(serverRunning)
{
endedCondition.await();
}
}
finally {
lock.unlock();
}
}
public Response serve(String uri, String method, Properties header, Properties params, Properties files )
{
if (uri.endsWith("/finish"))
{
try {
serverRunning = false;
stop();
endedCondition.signal();
}
finally {
lock.unlock();
}
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"));
}
return new NanoHTTPD.Response(HTTP_OK, MIME_HTML, "Acouchi");
}
private NanoHTTPD.Response ExecuteMethod(String methodName, String json)
{
if (methodName.equals("getCurrentContent"))
return new NanoHTTPD.Response(HTTP_OK, MIME_HTML, getCurrentContentAsJson());
try {
JSONArray jsonArray = new JSONArray(json);
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);
} catch (Exception exception) {
return showException(exception);
}
}
private Object executeMethodOnSomeClass(String methodName, Class[] parameterTypes, Object[] parameters) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException
{
try {
Method method = solo.getClass().getMethod(methodName, parameterTypes);
return method.invoke(solo, parameters);
} catch (Exception exception) {
android.util.Log.v("FFUUUU", "FF", exception);
}
Method method = this.getClass().getMethod(methodName, parameterTypes);
return method.invoke(this, parameters);
}
private NanoHTTPD.Response displayMethodResultAsJson(String methodName, Object result)
{
try {
JSONObject object = new JSONObject();
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;
if (name.equals("boolean")) return boolean.class;
return Class.forName(name);
}
private Object getConvertedValue(String name, String value)
{
if (name.equals("int")) return Integer.parseInt(value);
if (name.equals("long")) return Long.parseLong(value);
if (name.equals("double")) return Double.parseDouble(value);
if (name.equals("boolean")) return Boolean.parseBoolean(value);
if (name.equals("java.lang.Integer")) return Integer.parseInt(value);
if (name.equals("java.lang.Long")) return Long.parseLong(value);
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)
{
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();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment