Bug 780650 - Clean up dynamic dependencies from robocop on fennec. r=cpeterson

This commit is contained in:
Kartikaya Gupta 2012-08-14 08:55:58 -04:00
parent dd5c10cc90
commit 8c39cc3b65
6 changed files with 115 additions and 133 deletions

View File

@ -5,15 +5,10 @@
package @ANDROID_PACKAGE_NAME@;
import java.lang.Class;
import java.lang.ClassLoader;
import java.lang.reflect.Constructor;
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 java.lang.NoSuchMethodException;
import java.util.concurrent.SynchronousQueue;
import java.util.ArrayList;
@ -40,15 +35,16 @@ public class FennecNativeActions implements Actions {
// Objects for reflexive access of fennec classes.
private ClassLoader mClassLoader;
private Class mGel;
private Class mGe;
private Class mGas;
private Class mDrawListener;
private Method mRegisterGEL;
private Method mUnregisterGEL;
private Method mSendGE;
private Method mGetLayerClient;
private Class mApiClass;
private Class mEventListenerClass;
private Class mDrawListenerClass;
private Method mRegisterEventListener;
private Method mUnregisterEventListener;
private Method mBroadcastEvent;
private Method mSetDrawListener;
private Method mQuerySql;
private Object mRobocopApi;
private static final String LOGTAG = "FennecNativeActions";
public FennecNativeActions(Activity activity, Solo robocop, Instrumentation instrumentation, Assert asserter) {
@ -59,29 +55,19 @@ public class FennecNativeActions implements Actions {
// Set up reflexive access of java classes and methods.
try {
mClassLoader = activity.getClassLoader();
mGel = mClassLoader.loadClass("org.mozilla.gecko.util.GeckoEventListener");
mGe = mClassLoader.loadClass("org.mozilla.gecko.GeckoEvent");
mGas = mClassLoader.loadClass("org.mozilla.gecko.GeckoAppShell");
Class [] parameters = new Class[2];
parameters[0] = String.class;
parameters[1] = mGel;
mRegisterGEL = mGas.getMethod("registerEventListener", parameters);
mUnregisterGEL = mGas.getMethod("unregisterEventListener", parameters);
parameters = new Class[1];
parameters[0] = mGe;
mSendGE = mGas.getMethod("sendEventToGecko", parameters);
mGetLayerClient = activity.getClass().getMethod("getLayerClient");
Class gslc = mClassLoader.loadClass("org.mozilla.gecko.gfx.GeckoLayerClient");
mDrawListener = mClassLoader.loadClass("org.mozilla.gecko.gfx.GeckoLayerClient$DrawListener");
mSetDrawListener = gslc.getDeclaredMethod("setDrawListener", mDrawListener);
} catch (ClassNotFoundException e) {
FennecNativeDriver.log(LogLevel.ERROR, e);
} catch (SecurityException e) {
FennecNativeDriver.log(LogLevel.ERROR, e);
} catch (NoSuchMethodException e) {
FennecNativeDriver.log(LogLevel.ERROR, e);
} catch (IllegalArgumentException e) {
mApiClass = mClassLoader.loadClass("org.mozilla.gecko.RobocopAPI");
mEventListenerClass = mClassLoader.loadClass("org.mozilla.gecko.util.GeckoEventListener");
mDrawListenerClass = mClassLoader.loadClass("org.mozilla.gecko.gfx.GeckoLayerClient$DrawListener");
mRegisterEventListener = mApiClass.getMethod("registerEventListener", String.class, mEventListenerClass);
mUnregisterEventListener = mApiClass.getMethod("unregisterEventListener", String.class, mEventListenerClass);
mBroadcastEvent = mApiClass.getMethod("broadcastEvent", String.class, String.class);
mSetDrawListener = mApiClass.getMethod("setDrawListener", mDrawListenerClass);
mQuerySql = mApiClass.getMethod("querySql", String.class, String.class);
mRobocopApi = mApiClass.getConstructor(Activity.class).newInstance(activity);
} catch (Exception e) {
FennecNativeDriver.log(LogLevel.ERROR, e);
}
}
@ -144,7 +130,7 @@ public class FennecNativeActions implements Actions {
}
}
try {
mUnregisterGEL.invoke(null, mRegistrationParams);
mUnregisterEventListener.invoke(mRobocopApi, mRegistrationParams);
} catch (IllegalAccessException e) {
FennecNativeDriver.log(LogLevel.ERROR, e);
} catch (InvocationTargetException e) {
@ -192,7 +178,7 @@ public class FennecNativeActions implements Actions {
startTime = endTime;
}
try {
mUnregisterGEL.invoke(null, mRegistrationParams);
mUnregisterEventListener.invoke(mRobocopApi, mRegistrationParams);
} catch (IllegalAccessException e) {
FennecNativeDriver.log(LogLevel.ERROR, e);
} catch (InvocationTargetException e) {
@ -220,17 +206,14 @@ public class FennecNativeActions implements Actions {
FennecNativeDriver.log(FennecNativeDriver.LogLevel.DEBUG,
"waiting for "+geckoEvent);
try {
Class [] interfaces = new Class[1];
interfaces[0] = mGel;
Object[] finalParams = new Object[2];
finalParams[0] = geckoEvent;
GeckoEventExpecter expecter = new GeckoEventExpecter(geckoEvent, finalParams);
wakeInvocationHandler wIH = new wakeInvocationHandler(expecter);
Object proxy = Proxy.newProxyInstance(mClassLoader, interfaces, wIH);
Object proxy = Proxy.newProxyInstance(mClassLoader, new Class[] { mEventListenerClass }, wIH);
finalParams[1] = proxy;
mRegisterGEL.invoke(null, finalParams);
mRegisterEventListener.invoke(mRobocopApi, finalParams);
return expecter;
} catch (IllegalAccessException e) {
FennecNativeDriver.log(LogLevel.ERROR, e);
@ -242,11 +225,7 @@ public class FennecNativeActions implements Actions {
public void sendGeckoEvent(String geckoEvent, String data) {
try {
Method cbe = mGe.getMethod("createBroadcastEvent", String.class, String.class);
Object event = cbe.invoke(null, geckoEvent, data);
mSendGE.invoke(null, event);
} catch (NoSuchMethodException e) {
FennecNativeDriver.log(LogLevel.ERROR, e);
mBroadcastEvent.invoke(mRobocopApi, geckoEvent, data);
} catch (IllegalAccessException e) {
FennecNativeDriver.log(LogLevel.ERROR, e);
} catch (InvocationTargetException e) {
@ -284,8 +263,8 @@ public class FennecNativeActions implements Actions {
private static final int MAX_WAIT_MS = 90000;
PaintExpecter() throws IllegalAccessException, InvocationTargetException {
mLayerClient = mGetLayerClient.invoke(mGeckoApp);
mSetDrawListener.invoke(mLayerClient, Proxy.newProxyInstance(mClassLoader, new Class[] { mDrawListener }, new DrawListenerProxy(this)));
Object proxy = Proxy.newProxyInstance(mClassLoader, new Class[] { mDrawListenerClass }, new DrawListenerProxy(this));
mSetDrawListener.invoke(mRobocopApi, proxy);
}
void notifyOfEvent() {
@ -312,7 +291,7 @@ public class FennecNativeActions implements Actions {
}
}
try {
mSetDrawListener.invoke(mLayerClient, (Object)null);
mSetDrawListener.invoke(mRobocopApi, (Object)null);
} catch (Exception e) {
FennecNativeDriver.log(LogLevel.ERROR, e);
}
@ -360,7 +339,7 @@ public class FennecNativeActions implements Actions {
startTime = endTime;
}
try {
mSetDrawListener.invoke(mLayerClient, (Object)null);
mSetDrawListener.invoke(mRobocopApi, (Object)null);
} catch (Exception e) {
FennecNativeDriver.log(LogLevel.ERROR, e);
}
@ -415,30 +394,9 @@ public class FennecNativeActions implements Actions {
public Cursor querySql(String dbPath, String sql) {
try {
ClassLoader classLoader = mGeckoApp.getClassLoader();
Class sqlClass = classLoader.loadClass("org.mozilla.gecko.sqlite.SQLiteBridge");
Class stringClass = String.class;
Class stringArrayClass = String[].class;
Class appshell = classLoader.loadClass("org.mozilla.gecko.GeckoAppShell");
Class contextClass = Context.class;
Constructor bridgeConstructor = sqlClass.getConstructor(stringClass);
Method query = sqlClass.getMethod("rawQuery", stringClass, stringArrayClass);
Method loadSQLiteLibs = appshell.getMethod("loadSQLiteLibs", contextClass, stringClass);
Object bridge = bridgeConstructor.newInstance(dbPath);
String resourcePath = mGeckoApp.getApplication().getPackageResourcePath();
loadSQLiteLibs.invoke(null, mGeckoApp, resourcePath);
return (Cursor)query.invoke(bridge, sql, null);
} catch(ClassNotFoundException ex) {
Log.e(LOGTAG, "Error getting class", ex);
} catch(NoSuchMethodException ex) {
Log.e(LOGTAG, "Error getting method", ex);
return (Cursor)mQuerySql.invoke(mRobocopApi, dbPath, sql);
} catch(InvocationTargetException ex) {
Log.e(LOGTAG, "Error invoking method", ex);
} catch(InstantiationException ex) {
Log.e(LOGTAG, "Error calling constructor", ex);
} catch(IllegalAccessException ex) {
Log.e(LOGTAG, "Error using field", ex);
}

View File

@ -20,12 +20,10 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
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.opengl.GLSurfaceView;
@ -49,17 +47,16 @@ public class FennecNativeDriver implements Driver {
// Objects for reflexive access of fennec classes.
private ClassLoader mClassLoader;
private Class mGel;
private Class mGe;
private Class mGas;
private Method mRegisterGEL;
private Method mUnregisterGEL;
private Method mSendGE;
private Method _startFrameRecording;
private Method _stopFrameRecording;
private Method _startCheckerboardRecording;
private Method _stopCheckerboardRecording;
private Method _getPixels;
private Class mApiClass;
private Class mEventListenerClass;
private Class mPanningPerfClass;
private Method mRegisterEventListener;
private Method mGetPixels;
private Method mStartFrameRecording;
private Method mStopFrameRecording;
private Method mStartCheckerboardRecording;
private Method mStopCheckerboardRecording;
private Object mRobocopApi;
public enum LogLevel {
DEBUG(1),
@ -89,33 +86,20 @@ public class FennecNativeDriver implements Driver {
// Set up reflexive access of java classes and methods.
try {
mClassLoader = activity.getClassLoader();
mGel = mClassLoader.loadClass("org.mozilla.gecko.util.GeckoEventListener");
mGe = mClassLoader.loadClass("org.mozilla.gecko.GeckoEvent");
mGas = mClassLoader.loadClass("org.mozilla.gecko.GeckoAppShell");
Class [] parameters = new Class[2];
parameters[0] = String.class;
parameters[1] = mGel;
mRegisterGEL = mGas.getMethod("registerEventListener", parameters);
mUnregisterGEL = mGas.getMethod("unregisterEventListener", parameters);
parameters = new Class[1];
parameters[0] = mGe;
mSendGE = mGas.getMethod("sendEventToGecko", parameters);
Class gfx = mClassLoader.loadClass("org.mozilla.gecko.gfx.PanningPerfAPI");
_startFrameRecording = gfx.getDeclaredMethod("startFrameTimeRecording");
_stopFrameRecording = gfx.getDeclaredMethod("stopFrameTimeRecording");
_startCheckerboardRecording = gfx.getDeclaredMethod("startCheckerboardRecording");
_stopCheckerboardRecording = gfx.getDeclaredMethod("stopCheckerboardRecording");
mApiClass = mClassLoader.loadClass("org.mozilla.gecko.RobocopAPI");
mEventListenerClass = mClassLoader.loadClass("org.mozilla.gecko.util.GeckoEventListener");
mPanningPerfClass = mClassLoader.loadClass("org.mozilla.gecko.gfx.PanningPerfAPI");
Class layerView = mClassLoader.loadClass("org.mozilla.gecko.gfx.LayerView");
_getPixels = layerView.getDeclaredMethod("getPixels");
} catch (ClassNotFoundException e) {
log(LogLevel.ERROR, e);
} catch (SecurityException e) {
log(LogLevel.ERROR, e);
} catch (NoSuchMethodException e) {
log(LogLevel.ERROR, e);
} catch (IllegalArgumentException e) {
mRegisterEventListener = mApiClass.getMethod("registerEventListener", String.class, mEventListenerClass);
mGetPixels = mApiClass.getMethod("getViewPixels", View.class);
mStartFrameRecording = mPanningPerfClass.getDeclaredMethod("startFrameTimeRecording");
mStopFrameRecording = mPanningPerfClass.getDeclaredMethod("stopFrameTimeRecording");
mStartCheckerboardRecording = mPanningPerfClass.getDeclaredMethod("startCheckerboardRecording");
mStopCheckerboardRecording = mPanningPerfClass.getDeclaredMethod("stopCheckerboardRecording");
mRobocopApi = mApiClass.getConstructor(Activity.class).newInstance(activity);
} catch (Exception e) {
log(LogLevel.ERROR, e);
}
}
@ -189,8 +173,7 @@ public class FennecNativeDriver implements Driver {
public void startFrameRecording() {
try {
Object [] params = null;
_startFrameRecording.invoke(null, params);
mStartFrameRecording.invoke(null);
} catch (IllegalAccessException e) {
log(LogLevel.ERROR, e);
} catch (InvocationTargetException e) {
@ -199,12 +182,8 @@ public class FennecNativeDriver implements Driver {
}
public int stopFrameRecording() {
Class [] parameters = new Class[1];
parameters[0] = null;
try {
Object [] params = null;
List<Long> frames = (List<Long>)_stopFrameRecording.invoke(null, params);
List<Long> frames = (List<Long>)mStopFrameRecording.invoke(null);
int badness = 0;
for (int i = 1; i < frames.size(); i++) {
long frameTime = frames.get(i) - frames.get(i - 1);
@ -230,8 +209,7 @@ public class FennecNativeDriver implements Driver {
public void startCheckerboardRecording() {
try {
Object [] params = null;
_startCheckerboardRecording.invoke(null, params);
mStartCheckerboardRecording.invoke(null);
} catch (IllegalAccessException e) {
log(LogLevel.ERROR, e);
} catch (InvocationTargetException e) {
@ -240,12 +218,8 @@ public class FennecNativeDriver implements Driver {
}
public float stopCheckerboardRecording() {
Class [] parameters = new Class[1];
parameters[0] = null;
try {
Object [] params = null;
List<Float> checkerboard = (List<Float>)_stopCheckerboardRecording.invoke(null, params);
List<Float> checkerboard = (List<Float>)mStopCheckerboardRecording.invoke(null);
float total = 0;
for (float val : checkerboard) {
total += val;
@ -281,7 +255,7 @@ public class FennecNativeDriver implements Driver {
}
IntBuffer pixelBuffer;
try {
pixelBuffer = (IntBuffer)_getPixels.invoke(view);
pixelBuffer = (IntBuffer)mGetPixels.invoke(mRobocopApi, view);
} catch (Exception e) {
log(LogLevel.ERROR, e);
return null;
@ -368,11 +342,11 @@ public class FennecNativeDriver implements Driver {
//Setup scrollHandler to catch "robocop:scroll" events.
try {
Class [] interfaces = new Class[1];
interfaces[0] = mGel;
interfaces[0] = mEventListenerClass;
Object[] finalParams = new Object[2];
finalParams[0] = "robocop:scroll";
finalParams[1] = Proxy.newProxyInstance(mClassLoader, interfaces, new scrollHandler());
mRegisterGEL.invoke(null, finalParams);
mRegisterEventListener.invoke(mRobocopApi, finalParams);
} catch (IllegalAccessException e) {
log(LogLevel.ERROR, e);
} catch (InvocationTargetException e) {

View File

@ -100,6 +100,7 @@ FENNEC_JAVA_FILES = \
sqlite/SQLiteBridge.java \
sqlite/SQLiteBridgeException.java \
RemoteTabs.java \
RobocopAPI.java \
SetupScreen.java \
SiteIdentityPopup.java \
SuggestClient.java \

View File

@ -0,0 +1,49 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.gecko;
import org.mozilla.gecko.gfx.GeckoLayerClient;
import org.mozilla.gecko.gfx.LayerView;
import org.mozilla.gecko.sqlite.SQLiteBridge;
import org.mozilla.gecko.util.GeckoEventListener;
import android.app.Activity;
import android.database.Cursor;
import android.view.View;
import java.nio.IntBuffer;
public class RobocopAPI {
private final GeckoApp mGeckoApp;
public RobocopAPI(Activity activity) {
mGeckoApp = (GeckoApp)activity;
}
public void registerEventListener(String event, GeckoEventListener listener) {
GeckoAppShell.registerEventListener(event, listener);
}
public void unregisterEventListener(String event, GeckoEventListener listener) {
GeckoAppShell.unregisterEventListener(event, listener);
}
public void broadcastEvent(String subject, String data) {
GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent(subject, data));
}
public void setDrawListener(GeckoLayerClient.DrawListener listener) {
mGeckoApp.getLayerClient().setDrawListener(listener);
}
public Cursor querySql(String dbPath, String query) {
GeckoAppShell.loadSQLiteLibs(mGeckoApp, mGeckoApp.getApplication().getPackageResourcePath());
return new SQLiteBridge(dbPath).rawQuery(query, null);
}
public IntBuffer getViewPixels(View view) {
return ((LayerView)view).getPixels();
}
}

View File

@ -705,13 +705,13 @@ public class GeckoLayerClient
return layerPoint;
}
/** Used by robocop for testing purposes. Not for production use! This is called via reflection by robocop. */
/** Used by robocop for testing purposes. Not for production use! */
public void setDrawListener(DrawListener listener) {
mDrawListener = listener;
}
/** Used by robocop for testing purposes. Not for production use! This is used via reflection by robocop. */
public interface DrawListener {
/** Used by robocop for testing purposes. Not for production use! */
public static interface DrawListener {
public void drawFinished();
}
}

View File

@ -194,7 +194,7 @@ public class LayerView extends FrameLayout {
return mRenderer.getMaxTextureSize();
}
/** Used by robocop for testing purposes. Not for production use! This is called via reflection by robocop. */
/** Used by robocop for testing purposes. Not for production use! */
public IntBuffer getPixels() {
return mRenderer.getPixels();
}