gecko/build/mobile/robocop/FennecNativeDriver.java.in

298 lines
9.0 KiB
Java

#filter substitution
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Firefox Mobile Test Framework.
*
* The Initial Developer of the Original Code is Mozilla.
* Portions created by the Initial Developer are Copyright (C) 2011
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Trevor Fairey <tnfairey@gmail.com>
* David Burns <dburns@mozilla.com>
* Joel Maher <joel.maher@gmail.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
package @ANDROID_PACKAGE_NAME@;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.HashMap;
import java.util.List;
import java.lang.Class;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.Long;
import android.app.Activity;
import android.util.Log;
import android.view.View;
import org.json.*;
import com.jayway.android.robotium.solo.Solo;
public class FennecNativeDriver implements Driver {
// Map of IDs to element names.
private HashMap locators = null;
private Activity activity;
private Solo solo;
// Objects for reflexive access of fennec classes.
private ClassLoader classLoader;
private Class gel;
private Class ge;
private Class gas;
private Method registerGEL;
private Method unregisterGEL;
private Method sendGE;
private Method _startFrameRecording;
private Method _stopFrameRecording;
public FennecNativeDriver(Activity activity, Solo robocop){
this.activity = activity;
this.solo = robocop;
// Set up table of fennec_ids.
locators = convertTextToTable(getFile("/mnt/sdcard/fennec_ids.txt"));
// Set up reflexive access of java classes and methods.
try {
classLoader = activity.getClassLoader();
gel = classLoader.loadClass("org.mozilla.gecko.GeckoEventListener");
ge = classLoader.loadClass("org.mozilla.gecko.GeckoEvent");
gas = classLoader.loadClass("org.mozilla.gecko.GeckoAppShell");
Class [] parameters = new Class[2];
parameters[0] = String.class;
parameters[1] = gel;
registerGEL = gas.getMethod("registerGeckoEventListener", parameters);
unregisterGEL = gas.getMethod("unregisterGeckoEventListener", parameters);
parameters = new Class[1];
parameters[0] = ge;
sendGE = gas.getMethod("sendEventToGecko", parameters);
Class gfx = classLoader.loadClass("org.mozilla.gecko.gfx.PanningPerfAPI");
_startFrameRecording = gfx.getDeclaredMethod("startFrameTimeRecording");
_stopFrameRecording = gfx.getDeclaredMethod("stopFrameTimeRecording");
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
}
}
//Information on the location of the Gecko Frame.
private boolean geckoInfo = false;
private int geckoTop = 100;
private int geckoLeft = 0;
private int geckoHeight= 700;
private int geckoWidth = 1024;
private void getGeckoInfo() {
View geckoLayout = activity.findViewById(Integer.decode((String)locators.get("gecko_layout")));
if (geckoLayout != null) {
geckoTop = geckoLayout.getTop();
geckoLeft = geckoLayout.getLeft();
geckoWidth = geckoLayout.getWidth();
geckoHeight = geckoLayout.getHeight();
geckoInfo = true;
}
}
public int getGeckoTop() {
if(!geckoInfo) {
getGeckoInfo();
}
return geckoTop;
}
public int getGeckoLeft() {
if(!geckoInfo) {
getGeckoInfo();
}
return geckoLeft;
}
public int getGeckoHeight() {
if(!geckoInfo) {
getGeckoInfo();
}
return geckoHeight;
}
public int getGeckoWidth() {
if(!geckoInfo) {
getGeckoInfo();
}
return geckoWidth;
}
public Element findElement(Activity activity, String name) {
if (name == null)
throw new IllegalArgumentException("Can not findElements when passed a null");
if (locators.containsKey(name)){
return new FennecNativeElement(Integer.decode((String)locators.get(name)), activity, solo);
}
throw new RoboCopException("Element does not exist in the list");
}
public void startFrameRecording() {
try {
Object [] params = null;
_startFrameRecording.invoke(null, params);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
public int stopFrameRecording() {
Class [] parameters = new Class[1];
parameters[0] = null;
List frames;
try {
Object [] params = null;
frames = (List)_stopFrameRecording.invoke(null, params);
Object [] framearray = frames.toArray();
Long last = new Long(0);
Long threshold = new Long(17);
int numDelays = 0;
for (int i=0; i < framearray.length; i++) {
Long val = (Long)framearray[i];
if ((val - last) > threshold) {
numDelays++;
}
last = val;
}
return numDelays;
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
return 0;
}
class scrollHandler implements InvocationHandler {
public scrollHandler(){};
public Object invoke(Object proxy, Method method, Object[] args) {
try{
//Disect the JSON object into the appropriate variables
JSONObject jo = ((JSONObject)args[1]);
scrollHeight = jo.getInt("y");
height = jo.getInt("cheight");
//We don't want a height of 0. That means it's a bad response.
if( height > 0) {
pageHeight = jo.getInt("height");
}
} catch( Throwable e) {
Log.i("Robocop", "WARNING: ScrollReceived, but read wrong!");
}
return null;
}
}
public int getScrollHeight() {
return scrollHeight;
}
public int getPageHeight() {
return pageHeight;
}
public int getHeight() {
return height;
}
public int height=0;
public int scrollHeight=0;
public int pageHeight=10;
public void setupScrollHandling() {
//Setup scrollHandler to catch "robocop:scroll" events.
try {
Class [] interfaces = new Class[1];
interfaces[0] = gel;
Object[] finalParams = new Object[2];
finalParams[0] = "robocop:scroll";
finalParams[1] = Proxy.newProxyInstance(classLoader, interfaces, new scrollHandler());
registerGEL.invoke(null, finalParams);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
//Takes a filename, loads the file,
// and returns a string version of the entire file.
public static String getFile(String filename)
{
File file = new File(filename);
StringBuilder text = new StringBuilder();
try {
BufferedReader br = new BufferedReader(new FileReader(file));
String line;
while ((line = br.readLine()) != null) {
text.append(line);
text.append('\n');
}
} catch(IOException e) {
e.printStackTrace();
}
return text.toString();
}
// Takes a string of "key=value" pairs split by \n and creates a hash table.
public static HashMap convertTextToTable(String data)
{
HashMap retVal = new HashMap();
String[] lines = data.split("\n");
for (int i = 0; i < lines.length; i++) {
String[] parts = lines[i].split("=");
retVal.put(parts[0].trim(), parts[1].trim());
}
return retVal;
}
}