Merge backout, a=bustage fix
authorHub Figuière <hfiguiere@mozilla.com>
Tue, 10 Apr 2012 12:41:47 -0700
changeset 91347 1df10e8b5ce2d854b1dae34543bdfd4ec09e815d
parent 91346 57d8b862905b34ecb1011cc20741c44a31587821 (current diff)
parent 91345 24e84699e39548d1462b19deb57288d00bace05c (diff)
child 91348 c3276660b556c28e271c847cefdb2e5b9eec7971
push id22438
push usermbrubeck@mozilla.com
push dateWed, 11 Apr 2012 15:56:36 +0000
treeherdermozilla-central@63f78a93ae5c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbustage
milestone14.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge backout, a=bustage fix
--- a/build/mobile/robocop/FennecMochitestAssert.java.in
+++ b/build/mobile/robocop/FennecMochitestAssert.java.in
@@ -58,22 +58,22 @@ public class FennecMochitestAssert imple
     // Measure the time it takes to run test case
     private long mStartTime = 0;
 
     public FennecMochitestAssert() {
     }
 
     /** Write information to a logfile and logcat */
     public void dumpLog(String message) {
-        FennecNativeDriver.log(FennecNativeDriver.LogLevel.LOG_LEVEL_INFO, message);
+        FennecNativeDriver.log(FennecNativeDriver.LogLevel.INFO, message);
     }
 
     /** Write information to a logfile and logcat */
     public void dumpLog(String message, Throwable t) {
-        FennecNativeDriver.log(FennecNativeDriver.LogLevel.LOG_LEVEL_INFO, message, t);
+        FennecNativeDriver.log(FennecNativeDriver.LogLevel.INFO, message, t);
     }
 
     /** Set the filename used for dumpLog. */
     public void setLogFile(String filename) {
         FennecNativeDriver.setLogFile(filename);
 
         String message;
         if (!mLogStarted) {
--- a/build/mobile/robocop/FennecNativeActions.java.in
+++ b/build/mobile/robocop/FennecNativeActions.java.in
@@ -58,16 +58,18 @@ import android.os.SystemClock;
 import android.view.View;
 import android.view.KeyEvent;
 import android.util.Log;
 
 import org.json.*;
 
 import com.jayway.android.robotium.solo.Solo;
 
+import static @ANDROID_PACKAGE_NAME@.FennecNativeDriver.LogLevel;
+
 public class FennecNativeActions implements Actions {
     private Solo mSolo;
     private Instrumentation mInstr;
     private Activity mGeckoApp;
 
     // Objects for reflexive access of fennec classes.
     private ClassLoader mClassLoader;
     private Class mGel;
@@ -99,25 +101,25 @@ public class FennecNativeActions impleme
             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) {
-             e.printStackTrace();
-         } catch (SecurityException e) {
-             e.printStackTrace();
-         } catch (NoSuchMethodException e) {
-             e.printStackTrace();
-         } catch (IllegalArgumentException e) {
-             e.printStackTrace();
-         }
+        } 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) {
+            FennecNativeDriver.log(LogLevel.ERROR, e);
+        }
     }
 
     class wakeInvocationHandler implements InvocationHandler {
         private final GeckoEventExpecter mEventExpecter;
 
         public wakeInvocationHandler(GeckoEventExpecter expecter) {
             mEventExpecter = expecter;
         }
@@ -132,17 +134,17 @@ public class FennecNativeActions impleme
                 return this == args[0];
             }
             if(methodName.equals("clone")) {
                 return this;
             }
             if(methodName.equals("hashCode")) {
                 return 314;
             }
-            FennecNativeDriver.log(FennecNativeDriver.LogLevel.LOG_LEVEL_DEBUG, 
+            FennecNativeDriver.log(FennecNativeDriver.LogLevel.DEBUG, 
                 "Waking up on "+methodName);
             mEventExpecter.notifyOfEvent();
             return null;
         }
     }
 
     class GeckoEventExpecter implements EventExpecter {
         private final String mGeckoEvent;
@@ -154,80 +156,80 @@ public class FennecNativeActions impleme
             mRegistrationParams = registrationParams;
         }
 
         public synchronized void blockForEvent() {
             while (! mEventReceived) {
                 try {
                     this.wait();
                 } catch (InterruptedException ie) {
-                    ie.printStackTrace();
+                    FennecNativeDriver.log(LogLevel.ERROR, ie);
                     break;
                 }
             }
-            FennecNativeDriver.log(FennecNativeDriver.LogLevel.LOG_LEVEL_DEBUG,
+            FennecNativeDriver.log(FennecNativeDriver.LogLevel.DEBUG,
                 "unblocked on expecter for " + mGeckoEvent);
         }
 
         public synchronized boolean eventReceived() {
             return mEventReceived;
         }
 
         void notifyOfEvent() {
             try {
                 mUnregisterGEL.invoke(null, mRegistrationParams);
             } catch (IllegalAccessException e) {
-                e.printStackTrace();
+                FennecNativeDriver.log(LogLevel.ERROR, e);
             } catch (InvocationTargetException e) {
-                e.printStackTrace();
+                FennecNativeDriver.log(LogLevel.ERROR, e);
             }
-            FennecNativeDriver.log(FennecNativeDriver.LogLevel.LOG_LEVEL_DEBUG,
+            FennecNativeDriver.log(FennecNativeDriver.LogLevel.DEBUG,
                 "received event " + mGeckoEvent);
             synchronized (this) {
                 mEventReceived = true;
                 this.notifyAll();
             }
         }
     }
     
     public EventExpecter expectGeckoEvent(String geckoEvent) {
-        FennecNativeDriver.log(FennecNativeDriver.LogLevel.LOG_LEVEL_DEBUG,
+        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);
             finalParams[1] = proxy;
             mRegisterGEL.invoke(null, finalParams);
             
             return expecter;
         } catch (IllegalAccessException e) {
-            e.printStackTrace();
+            FennecNativeDriver.log(LogLevel.ERROR, e);
         } catch (InvocationTargetException e) {
-            e.printStackTrace();
+            FennecNativeDriver.log(LogLevel.ERROR, e);
         }
         return null;
     }
 
     class DrawListenerProxy implements InvocationHandler {
         private final PaintExpecter mPaintExpecter;
 
         DrawListenerProxy(PaintExpecter paintExpecter) {
             mPaintExpecter = paintExpecter;
         }
 
         public Object invoke(Object proxy, Method method, Object[] args) {
             String methodName = method.getName();
             if ("drawFinished".equals(methodName)) {
-                FennecNativeDriver.log(FennecNativeDriver.LogLevel.LOG_LEVEL_DEBUG,
+                FennecNativeDriver.log(FennecNativeDriver.LogLevel.DEBUG,
                     "Received drawFinished notification");
                 mPaintExpecter.notifyOfEvent();
             } else if ("toString".equals(methodName)) {
                 return "DrawListenerProxy";
             } else if ("equals".equals(methodName)) {
                 return false;
             } else if ("hashCode".equals(methodName)) {
                 return 0;
@@ -252,74 +254,74 @@ public class FennecNativeActions impleme
             }
         }
 
         public synchronized void blockForEvent() {
             while (!mPaintDone) {
                 try {
                     this.wait();
                 } catch (InterruptedException ie) {
-                    ie.printStackTrace();
+                    FennecNativeDriver.log(LogLevel.ERROR, ie);
                     break;
                 }
             }
             try {
                 mSetDrawListener.invoke(mLayerClient, (Object)null);
             } catch (Exception e) {
-                e.printStackTrace();
+                FennecNativeDriver.log(LogLevel.ERROR, e);
             }
         }
 
         public synchronized boolean eventReceived() {
             return mPaintDone;
         }
 
         public synchronized void blockUntilClear(long millis) {
             if (millis <= 0) {
                 throw new IllegalArgumentException("millis must be > 0");
             }
             // wait for at least one event
             while (!mPaintDone) {
                 try {
                     this.wait();
                 } catch (InterruptedException ie) {
-                    ie.printStackTrace();
+                    FennecNativeDriver.log(LogLevel.ERROR, ie);
                     break;
                 }
             }
             // now wait for a period of millis where we don't get an event
             long startTime = SystemClock.uptimeMillis();
             while (true) {
                 try {
                     this.wait(millis);
                 } catch (InterruptedException ie) {
-                    ie.printStackTrace();
+                    FennecNativeDriver.log(LogLevel.ERROR, ie);
                     break;
                 }
                 long endTime = SystemClock.uptimeMillis();
                 if (endTime - startTime >= millis) {
                     // success
                     break;
                 }
                 // we got a notify() before we could wait long enough, so we need to start over
                 startTime = endTime;
             }
             try {
                 mSetDrawListener.invoke(mLayerClient, (Object)null);
             } catch (Exception e) {
-                e.printStackTrace();
+                FennecNativeDriver.log(LogLevel.ERROR, e);
             }
         }
     }
 
     public RepeatedEventExpecter expectPaint() {
         try {
             return new PaintExpecter();
         } catch (Exception e) {
-            e.printStackTrace();
+            FennecNativeDriver.log(LogLevel.ERROR, e);
             return null;
         }
     }
 
     public void sendSpecialKey(SpecialKey button) {
         switch(button) {
             case DOWN:
                 mInstr.sendCharacterSync(KeyEvent.KEYCODE_DPAD_DOWN);
--- a/build/mobile/robocop/FennecNativeDriver.java.in
+++ b/build/mobile/robocop/FennecNativeDriver.java.in
@@ -73,37 +73,37 @@ public class FennecNativeDriver implemen
     private static final int FRAME_TIME_THRESHOLD = 17;     // allow 17ms per frame (~60fps)
 
     // Map of IDs to element names.
     private HashMap mLocators = null;
     private Activity mActivity;
     private Solo mSolo;
 
     private static String mLogFile = null;
-    private static LogLevel mLogLevel = LogLevel.LOG_LEVEL_INFO;
+    private static LogLevel mLogLevel = LogLevel.INFO;
 
     // 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;
 
     public enum LogLevel {
-        LOG_LEVEL_DEBUG(1), 
-        LOG_LEVEL_INFO(2),    
-        LOG_LEVEL_WARN(3), 
-        LOG_LEVEL_ERROR(4);
+        DEBUG(1),
+        INFO(2),
+        WARN(3),
+        ERROR(4);
 
         private int mValue;
         LogLevel(int value) {
             mValue = value;
         }
         public boolean isEnabled(LogLevel configuredLevel) {
             return mValue >= configuredLevel.getValue();
         }
@@ -137,25 +137,25 @@ public class FennecNativeDriver implemen
             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");
 
             Class layerView = mClassLoader.loadClass("org.mozilla.gecko.gfx.LayerView");
             _getPixels = layerView.getDeclaredMethod("getPixels");
-         } catch (ClassNotFoundException e) {
-             e.printStackTrace();
-         } catch (SecurityException e) {
-             e.printStackTrace();
-         } catch (NoSuchMethodException e) {
-             e.printStackTrace();
-         } catch (IllegalArgumentException e) {
-             e.printStackTrace();
-         }
+        } catch (ClassNotFoundException e) {
+            log(LogLevel.ERROR, e);
+        } catch (SecurityException e) {
+            log(LogLevel.ERROR, e);
+        } catch (NoSuchMethodException e) {
+            log(LogLevel.ERROR, e);
+        } catch (IllegalArgumentException e) {
+            log(LogLevel.ERROR, e);
+        }
     }
 
     //Information on the location of the Gecko Frame.
     private boolean mGeckoInfo = false;
     private int mGeckoTop = 100;
     private int mGeckoLeft = 0;
     private int mGeckoHeight= 700;
     private int mGeckoWidth = 1024;
@@ -213,19 +213,19 @@ public class FennecNativeDriver implemen
         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();
+            log(LogLevel.ERROR, e);
         } catch (InvocationTargetException e) {
-            e.printStackTrace();
+            log(LogLevel.ERROR, e);
         }
     }
 
     public int stopFrameRecording() {
         Class [] parameters = new Class[1];
         parameters[0] = null;
 
         try {
@@ -234,80 +234,80 @@ public class FennecNativeDriver implemen
             int numDelays = 0;
             for (int i = 1; i < frames.size(); i++) {
                 if (frames.get(i) - frames.get(i-1) > FRAME_TIME_THRESHOLD) {
                     numDelays++;
                 }
             }
             return numDelays;
         } catch (IllegalAccessException e) {
-            e.printStackTrace();
+            log(LogLevel.ERROR, e);
         } catch (InvocationTargetException e) {
-            e.printStackTrace();
+            log(LogLevel.ERROR, e);
         }
 
         return 0;
     }
 
     public void startCheckerboardRecording() {
         try {
             Object [] params = null;
             _startCheckerboardRecording.invoke(null, params);
         } catch (IllegalAccessException e) {
-            e.printStackTrace();
+            log(LogLevel.ERROR, e);
         } catch (InvocationTargetException e) {
-            e.printStackTrace();
+            log(LogLevel.ERROR, e);
         }
     }
 
     public float stopCheckerboardRecording() {
         Class [] parameters = new Class[1];
         parameters[0] = null;
 
         try {
             Object [] params = null;
             List<Float> checkerboard = (List<Float>)_stopCheckerboardRecording.invoke(null, params);
             float completeness = 0;
             for (float val : checkerboard) {
                 completeness += (1.0f - val);
             }
             return completeness / (float)checkerboard.size();
         } catch (IllegalAccessException e) {
-            e.printStackTrace();
+            log(LogLevel.ERROR, e);
         } catch (InvocationTargetException e) {
-            e.printStackTrace();
+            log(LogLevel.ERROR, e);
         }
 
         return 0.0f;
     }
 
     private View getSurfaceView() {
         try {
             Class c = Class.forName("org.mozilla.gecko.gfx.LayerView");
             for (View v : mSolo.getCurrentViews()) {
                 if (c.isInstance(v)) {
                     return v;
                 }
             }
         } catch (ClassNotFoundException e) {
-            e.printStackTrace();
+            log(LogLevel.ERROR, e);
         }
         return null;
     }
 
     public PaintedSurface getPaintedSurface() {
         View view = getSurfaceView();
         if (view == null) {
             return null;
         }
         IntBuffer pixelBuffer;
         try {
             pixelBuffer = (IntBuffer)_getPixels.invoke(view);
         } catch (Exception e) {
-            e.printStackTrace();
+            log(LogLevel.ERROR, e);
             return null;
         }
 
         // now we need to (1) flip the image, because GL likes to do things up-side-down,
         // and (2) rearrange the bits from AGBR-8888 to ARGB-8888.
         int w = view.getWidth();
         int h = view.getHeight();
         pixelBuffer.position(0);
@@ -336,17 +336,17 @@ public class FennecNativeDriver implemen
                     dos.close();
                 }
                 // closing dos automatically closes bos
                 if (fos != null) {
                     fos.flush();
                     fos.close();
                 }
             } catch (IOException e) {
-                e.printStackTrace();
+                log(LogLevel.ERROR, e);
                 throw new RoboCopException("exception closing pixel writer on file: " + mapFile);
             }
         }
         return new PaintedSurface(mapFile, w, h);
     }
 
     public int mHeight=0;
     public int mScrollHeight=0;
@@ -361,17 +361,17 @@ public class FennecNativeDriver implemen
                 mScrollHeight = jo.getInt("y");
                 mHeight = jo.getInt("cheight");
                 // We don't want a height of 0. That means it's a bad response.
                 if (mHeight > 0) {
                     mPageHeight = jo.getInt("height");
                 }
 
             } catch( Throwable e) {
-                FennecNativeDriver.log(FennecNativeDriver.LogLevel.LOG_LEVEL_WARN, 
+                FennecNativeDriver.log(FennecNativeDriver.LogLevel.WARN, 
                     "WARNING: ScrollReceived, but read wrong!");
             }
             return null;
         }
     }
 
     public int getScrollHeight() {
         return mScrollHeight;
@@ -388,19 +388,19 @@ public class FennecNativeDriver implemen
         try {
             Class [] interfaces = new Class[1];
             interfaces[0] = mGel;
             Object[] finalParams = new Object[2];
             finalParams[0] = "robocop:scroll";
             finalParams[1] = Proxy.newProxyInstance(mClassLoader, interfaces, new scrollHandler());
             mRegisterGEL.invoke(null, finalParams);
         } catch (IllegalAccessException e) {
-            e.printStackTrace();
+            log(LogLevel.ERROR, e);
         } catch (InvocationTargetException e) {
-            e.printStackTrace();
+            log(LogLevel.ERROR, e);
         }
 
     }
 
     /**
      *  Takes a filename, loads the file, and returns a string version of the entire file.
      */
     public static String getFile(String filename)
@@ -411,18 +411,18 @@ public class FennecNativeDriver implemen
         try {
             br = new BufferedReader(new FileReader(filename));
             String line;
 
             while ((line = br.readLine()) != null) {
                 text.append(line);
                 text.append('\n');
             }
-        } catch(IOException e) {
-            e.printStackTrace();
+        } catch (IOException e) {
+            log(LogLevel.ERROR, e);
         } finally {
             try {
                 br.close();
             } catch (IOException e) {
             }
         }
         return text.toString();    
     }
@@ -488,19 +488,19 @@ public class FennecNativeDriver implemen
             }
             // PrintWriter doesn't throw IOE but sets an error flag instead,
             // so check for that
             if (pw.checkError()) {
                 Log.e("Robocop", "exception with file writer on: " + mLogFile);
             }
         }
 
-        if (level == LogLevel.LOG_LEVEL_INFO) {
+        if (level == LogLevel.INFO) {
             Log.i("Robocop", message, t);
-        } else if (level == LogLevel.LOG_LEVEL_DEBUG) {
+        } else if (level == LogLevel.DEBUG) {
             Log.d("Robocop", message, t);
-        } else if (level == LogLevel.LOG_LEVEL_WARN) {
+        } else if (level == LogLevel.WARN) {
             Log.w("Robocop", message, t);
-        } else if (level == LogLevel.LOG_LEVEL_ERROR) {
+        } else if (level == LogLevel.ERROR) {
             Log.e("Robocop", message, t);
         }
     }
 }
--- a/build/mobile/robocop/FennecNativeElement.java.in
+++ b/build/mobile/robocop/FennecNativeElement.java.in
@@ -71,29 +71,29 @@ public class FennecNativeElement impleme
     public void click() {
         final SynchronousQueue syncQueue = new SynchronousQueue();
         mActivity.runOnUiThread(
             new Runnable() {
                 public void run() {
                     View view = (View)mActivity.findViewById(mId);
                     if(view != null) {
                         if (!view.performClick()) {
-                            FennecNativeDriver.log(FennecNativeDriver.LogLevel.LOG_LEVEL_WARN,
+                            FennecNativeDriver.log(FennecNativeDriver.LogLevel.WARN,
                                 "Robocop called click on an element with no listener");
                         }
                     } else {
                         throw new RoboCopException("click: unable to find view "+mId); 
                     }
                     syncQueue.offer(new Object());
                 }
             });
         try {
             syncQueue.take();
         } catch (InterruptedException e) {
-            e.printStackTrace();
+            FennecNativeDriver.log(FennecNativeDriver.LogLevel.ERROR, e);
         }
     }
 
     private Object mText;
 
     public String getText() {
         final SynchronousQueue syncQueue = new SynchronousQueue();
         mActivity.runOnUiThread(
@@ -124,17 +124,17 @@ public class FennecNativeElement impleme
                     syncQueue.offer(new Object());
                 } // end of run() method definition
             } // end of anonymous Runnable object instantiation
         );
         try {     
             // Wait for the UiThread code to finish running
             syncQueue.take();
         } catch (InterruptedException e) {
-            e.printStackTrace();
+            FennecNativeDriver.log(FennecNativeDriver.LogLevel.ERROR, e);
         }
         if (mText == null) {
             throw new RoboCopException("getText: Text is null for view "+mId);
         }
         return mText.toString();
     }
 
     private boolean mDisplayed;
@@ -150,14 +150,14 @@ public class FennecNativeElement impleme
                         mDisplayed = true;
                     }
                     syncQueue.offer(new Object());
                 }
             });
         try {
             syncQueue.take();
         } catch (InterruptedException e) {
-            e.printStackTrace();
+            FennecNativeDriver.log(FennecNativeDriver.LogLevel.ERROR, e);
         }
         return mDisplayed;
     }
 
 }
--- a/build/mobile/robocop/FennecTalosAssert.java.in
+++ b/build/mobile/robocop/FennecTalosAssert.java.in
@@ -41,22 +41,22 @@ package @ANDROID_PACKAGE_NAME@;
 public class FennecTalosAssert implements Assert {
     
     public FennecTalosAssert() { }
 
     /**
      *  Write information to a logfile and logcat
      */
     public void dumpLog(String message) {
-        FennecNativeDriver.log(FennecNativeDriver.LogLevel.LOG_LEVEL_INFO, message);
+        FennecNativeDriver.log(FennecNativeDriver.LogLevel.INFO, message);
     }
 
     /** Write information to a logfile and logcat */
     public void dumpLog(String message, Throwable t) {
-        FennecNativeDriver.log(FennecNativeDriver.LogLevel.LOG_LEVEL_INFO, message, t);
+        FennecNativeDriver.log(FennecNativeDriver.LogLevel.INFO, message, t);
     }
 
     /**
      *  Set the filename used for dumpLog.
      */
     public void setLogFile(String filename) {
         FennecNativeDriver.setLogFile(filename);
     }
--- a/build/mobile/robocop/PaintedSurface.java.in
+++ b/build/mobile/robocop/PaintedSurface.java.in
@@ -24,19 +24,19 @@ public class PaintedSurface {
         
         try {
             File f = new File(filename);
             int pixelSize = (int)f.length();
             
             FileInputStream pixelFile = new FileInputStream(filename);
             mPixelBuffer = pixelFile.getChannel().map(FileChannel.MapMode.READ_ONLY, 0, pixelSize);
         } catch (java.io.FileNotFoundException e) {
-            e.printStackTrace();
+            FennecNativeDriver.log(FennecNativeDriver.LogLevel.ERROR, e);
         } catch (java.io.IOException e) {
-            e.printStackTrace();
+            FennecNativeDriver.log(FennecNativeDriver.LogLevel.ERROR, e);
         }
     }
 
     public final int getPixelAt(int x, int y) {
         if (mPixelBuffer == null) {
             throw new RoboCopException("Trying to access PaintedSurface with no active PixelBuffer");
         }
 
--- a/js/src/jsanalyze.cpp
+++ b/js/src/jsanalyze.cpp
@@ -1043,23 +1043,24 @@ ScriptAnalysis::addVariable(JSContext *c
 }
 
 inline void
 ScriptAnalysis::killVariable(JSContext *cx, LifetimeVariable &var, unsigned offset,
                              LifetimeVariable **&saved, unsigned &savedCount)
 {
     if (!var.lifetime) {
         /* Make a point lifetime indicating the write. */
-        if (!var.saved)
-            saved[savedCount++] = &var;
-        var.saved = cx->typeLifoAlloc().new_<Lifetime>(offset, var.savedEnd, var.saved);
-        if (!var.saved) {
+        Lifetime *lifetime = cx->typeLifoAlloc().new_<Lifetime>(offset, var.savedEnd, var.saved);
+        if (!lifetime) {
             setOOM(cx);
             return;
         }
+        if (!var.saved)
+            saved[savedCount++] = &var;
+        var.saved = lifetime;
         var.saved->write = true;
         var.savedEnd = 0;
         return;
     }
 
     JS_ASSERT_IF(!var.ensured, offset < var.lifetime->start);
     unsigned start = var.lifetime->start;
 
--- a/js/src/jsinfer.cpp
+++ b/js/src/jsinfer.cpp
@@ -2721,23 +2721,23 @@ TypeObject::getFromPrototypes(JSContext 
     if (!proto)
         return;
 
     if (proto->getType(cx)->unknownProperties()) {
         types->addType(cx, Type::UnknownType());
         return;
     }
 
-    TypeSet *protoTypes = proto->type()->getProperty(cx, id, false);
+    TypeSet *protoTypes = proto->getType(cx)->getProperty(cx, id, false);
     if (!protoTypes)
         return;
 
     protoTypes->addSubset(cx, types);
 
-    proto->type()->getFromPrototypes(cx, id, protoTypes);
+    proto->getType(cx)->getFromPrototypes(cx, id, protoTypes);
 }
 
 static inline void
 UpdatePropertyType(JSContext *cx, TypeSet *types, JSObject *obj, const Shape *shape, bool force)
 {
     types->setOwnProperty(cx, false);
     if (!shape->writable())
         types->setOwnProperty(cx, true);
@@ -5305,18 +5305,20 @@ IgnorePushed(const jsbytecode *pc, unsig
 
 bool
 JSScript::makeTypes(JSContext *cx)
 {
     JS_ASSERT(!types);
 
     if (!cx->typeInferenceEnabled()) {
         types = (TypeScript *) cx->calloc_(sizeof(TypeScript));
-        if (!types)
+        if (!types) {
+            js_ReportOutOfMemory(cx);
             return false;
+        }
         new(types) TypeScript();
         return true;
     }
 
     AutoEnterTypeInference enter(cx);
 
     unsigned count = TypeScript::NumTypeSets(this);
 
@@ -5515,26 +5517,34 @@ JSObject::splicePrototype(JSContext *cx,
     }
 
     return true;
 }
 
 void
 JSObject::makeLazyType(JSContext *cx)
 {
-    JS_ASSERT(cx->typeInferenceEnabled() && hasLazyType());
-    AutoEnterTypeInference enter(cx);
+    JS_ASSERT(hasLazyType());
 
     TypeObject *type = cx->compartment->types.newTypeObject(cx, NULL,
                                                             JSProto_Object, getProto());
     if (!type) {
-        cx->compartment->types.setPendingNukeTypes(cx);
+        if (cx->typeInferenceEnabled())
+            cx->compartment->types.setPendingNukeTypes(cx);
         return;
     }
 
+    if (!cx->typeInferenceEnabled()) {
+        /* This can only happen if types were previously nuked. */
+        type_ = type;
+        return;
+    }
+
+    AutoEnterTypeInference enter(cx);
+
     /* Fill in the type according to the state of this object. */
 
     type->singleton = this;
 
     if (isFunction() && toFunction()->isInterpreted()) {
         type->interpretedFunction = toFunction();
         JSScript *script = type->interpretedFunction->script();
         if (script->uninlineable)
--- a/js/src/jsinferinlines.h
+++ b/js/src/jsinferinlines.h
@@ -324,33 +324,35 @@ MarkIteratorUnknown(JSContext *cx)
     if (cx->typeInferenceEnabled())
         MarkIteratorUnknownSlow(cx);
 }
 
 /*
  * Monitor a javascript call, either on entry to the interpreter or made
  * from within the interpreter.
  */
-inline void
+inline bool
 TypeMonitorCall(JSContext *cx, const js::CallArgs &args, bool constructing)
 {
     extern void TypeMonitorCallSlow(JSContext *cx, JSObject *callee,
                                     const CallArgs &args, bool constructing);
 
     JSObject *callee = &args.callee();
     if (callee->isFunction()) {
         JSFunction *fun = callee->toFunction();
         if (fun->isInterpreted()) {
             JSScript *script = fun->script();
             if (!script->ensureRanAnalysis(cx, fun->environment()))
-                return;
+                return false;
             if (cx->typeInferenceEnabled())
                 TypeMonitorCallSlow(cx, callee, args, constructing);
         }
     }
+
+    return true;
 }
 
 inline bool
 TrackPropertyTypes(JSContext *cx, JSObject *obj, jsid id)
 {
     if (!cx->typeInferenceEnabled() || obj->hasLazyType() || obj->type()->unknownProperties())
         return false;
 
--- a/js/src/jsinterp.cpp
+++ b/js/src/jsinterp.cpp
@@ -510,17 +510,18 @@ js::InvokeKernel(JSContext *cx, CallArgs
     }
 
     /* Invoke native functions. */
     JSFunction *fun = callee.toFunction();
     JS_ASSERT_IF(construct, !fun->isNativeConstructor());
     if (fun->isNative())
         return CallJSNative(cx, fun->native(), args);
 
-    TypeMonitorCall(cx, args, construct);
+    if (!TypeMonitorCall(cx, args, construct))
+        return false;
 
     /* Get pointer to new frame/slots, prepare arguments. */
     InvokeFrameGuard ifg;
     if (!cx->stack.pushInvokeFrame(cx, args, initial, &ifg))
         return false;
 
     /* Now that the new frame is rooted, maybe create a call object. */
     StackFrame *fp = ifg.fp();
@@ -2688,17 +2689,18 @@ BEGIN_CASE(JSOP_FUNCALL)
         Value *newsp = args.spAfterCall();
         TypeScript::Monitor(cx, script, regs.pc, newsp[-1]);
         regs.sp = newsp;
         CHECK_INTERRUPT_HANDLER();
         len = JSOP_CALL_LENGTH;
         DO_NEXT_OP(len);
     }
 
-    TypeMonitorCall(cx, args, construct);
+    if (!TypeMonitorCall(cx, args, construct))
+        goto error;
 
     InitialFrameFlags initial = construct ? INITIAL_CONSTRUCT : INITIAL_NONE;
 
     JSScript *newScript = fun->script();
 
     if (newScript->compileAndGo && newScript->hasClearedGlobal()) {
         JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_CLEARED_SCOPE);
         goto error;
--- a/js/src/methodjit/BaseCompiler.h
+++ b/js/src/methodjit/BaseCompiler.h
@@ -133,19 +133,17 @@ class LinkerHelper : public JSC::LinkBuf
 #endif
     { }
 
     ~LinkerHelper() {
         JS_ASSERT(verifiedRange);
     }
 
     bool verifyRange(const JSC::JITCode &other) {
-#ifdef DEBUG
-        verifiedRange = true;
-#endif
+        markVerified();
 #ifdef JS_CPU_X64
         return VerifyRange(m_code, m_size, other.start(), other.size());
 #else
         return true;
 #endif
     }
 
     bool verifyRange(JITChunk *chunk) {
@@ -157,16 +155,17 @@ class LinkerHelper : public JSC::LinkBuf
         // The pool is incref'd after this call, so it's necessary to release()
         // on any failure.
         JSScript *script = cx->fp()->script();
         JSC::ExecutableAllocator *allocator = script->compartment()->jaegerCompartment()->execAlloc();
         allocator->setDestroyCallback(Probes::discardExecutableRegion);
         JSC::ExecutablePool *pool;
         m_code = executableAllocAndCopy(masm, allocator, &pool);
         if (!m_code) {
+            markVerified();
             js_ReportOutOfMemory(cx);
             return NULL;
         }
         m_size = masm.size();   // must come after call to executableAllocAndCopy()!
         return pool;
     }
 
     JSC::CodeLocationLabel finalize(VMFrame &f) {
@@ -181,16 +180,23 @@ class LinkerHelper : public JSC::LinkBuf
         if (!jump.isSet())
             return;
         link(jump.get(), label);
     }
 
     size_t size() const {
         return m_size;
     }
+
+  protected:
+    void markVerified() {
+#ifdef DEBUG
+        verifiedRange = true;
+#endif
+    }
 };
 
 class NativeStubLinker : public LinkerHelper
 {
   public:
 #ifdef JS_CPU_X64
     typedef JSC::MacroAssembler::DataLabelPtr FinalJump;
 #else
--- a/js/src/methodjit/InvokeHelpers.cpp
+++ b/js/src/methodjit/InvokeHelpers.cpp
@@ -293,17 +293,18 @@ UncachedInlineCall(VMFrame &f, InitialFr
     JSFunction *newfun = args.callee().toFunction();
     JSScript *newscript = newfun->script();
 
     bool construct = InitialFrameFlagsAreConstructing(initial);
 
     bool newType = construct && cx->typeInferenceEnabled() &&
         types::UseNewType(cx, f.script(), f.pc());
 
-    types::TypeMonitorCall(cx, args, construct);
+    if (!types::TypeMonitorCall(cx, args, construct))
+        return false;
 
     /* Try to compile if not already compiled. */
     CompileStatus status = CanMethodJIT(cx, newscript, newscript->code, construct, CompileRequest_Interpreter);
     if (status == Compile_Error) {
         /* A runtime exception was thrown, get out. */
         return false;
     }
     if (status == Compile_Abort)
--- a/js/src/methodjit/MonoIC.cpp
+++ b/js/src/methodjit/MonoIC.cpp
@@ -217,16 +217,17 @@ class EqualityICLinker : public LinkerHe
     { }
 
     bool init(JSContext *cx) {
         JSC::ExecutablePool *pool = LinkerHelper::init(cx);
         if (!pool)
             return false;
         JS_ASSERT(!f.regs.inlined());
         if (!f.chunk()->execPools.append(pool)) {
+            markVerified();
             pool->release();
             js_ReportOutOfMemory(cx);
             return false;
         }
         return true;
     }
 };
 
@@ -433,16 +434,17 @@ NativeStubLinker::init(JSContext *cx)
     if (!pool)
         return false;
 
     NativeCallStub stub;
     stub.pc = pc;
     stub.pool = pool;
     stub.jump = locationOf(done);
     if (!chunk->nativeCallStubs.append(stub)) {
+        markVerified();
         pool->release();
         return false;
     }
 
     return true;
 }
 
 /*
--- a/js/src/methodjit/PolyIC.cpp
+++ b/js/src/methodjit/PolyIC.cpp
@@ -81,16 +81,17 @@ class PICLinker : public LinkerHelper
       : LinkerHelper(masm, JSC::METHOD_CODE), ic(ic)
     { }
 
     bool init(JSContext *cx) {
         JSC::ExecutablePool *pool = LinkerHelper::init(cx);
         if (!pool)
             return false;
         if (!ic.addPool(cx, pool)) {
+            markVerified();
             pool->release();
             js_ReportOutOfMemory(cx);
             return false;
         }
         return true;
     }
 };
 
--- a/js/src/methodjit/Retcon.cpp
+++ b/js/src/methodjit/Retcon.cpp
@@ -357,16 +357,18 @@ ExpandInlineFrames(JSCompartment *compar
 void
 ClearAllFrames(JSCompartment *compartment)
 {
     if (!compartment || !compartment->hasJaegerCompartment())
         return;
 
     ExpandInlineFrames(compartment);
 
+    compartment->types.recompilations++;
+
     for (VMFrame *f = compartment->jaegerCompartment()->activeFrame();
          f != NULL;
          f = f->previous) {
 
         Recompiler::patchFrame(compartment, f, f->fp()->script());
 
         // Clear ncode values from all frames associated with the VMFrame.
         // Patching the VMFrame's return address will cause all its frames to
--- a/mobile/android/app/mobile.js
+++ b/mobile/android/app/mobile.js
@@ -358,17 +358,17 @@ pref("places.frecency.tempRedirectVisitB
 pref("places.frecency.defaultVisitBonus", 0);
 pref("places.frecency.unvisitedBookmarkBonus", 140);
 pref("places.frecency.unvisitedTypedBonus", 200);
 
 // disable color management
 pref("gfx.color_management.mode", 0);
 #ifdef ANDROID
 // 0=fixed margin, 1=velocity bias, 2=dynamic resolution, 3=no margins
-pref("gfx.displayport.strategy", 0);
+pref("gfx.displayport.strategy", 1);
 #endif
 
 // don't allow JS to move and resize existing windows
 pref("dom.disable_window_move_resize", true);
 
 // prevent click image resizing for nsImageDocument
 pref("browser.enable_click_image_resizing", false);
 
--- a/mobile/android/base/gfx/DisplayPortCalculator.java
+++ b/mobile/android/base/gfx/DisplayPortCalculator.java
@@ -10,17 +10,17 @@ import android.graphics.RectF;
 import android.util.Log;
 import org.mozilla.gecko.FloatUtils;
 import org.mozilla.gecko.GeckoAppShell;
 
 final class DisplayPortCalculator {
     private static final String LOGTAG = "GeckoDisplayPortCalculator";
     private static final PointF ZERO_VELOCITY = new PointF(0, 0);
 
-    private static DisplayPortStrategy sStrategy = new FixedMarginStrategy();
+    private static DisplayPortStrategy sStrategy = new VelocityBiasStrategy();
 
     static DisplayPortMetrics calculate(ImmutableViewportMetrics metrics, PointF velocity) {
         return sStrategy.calculate(metrics, (velocity == null ? ZERO_VELOCITY : velocity));
     }
 
     static boolean aboutToCheckerboard(ImmutableViewportMetrics metrics, PointF velocity, DisplayPortMetrics displayPort) {
         if (displayPort == null) {
             return true;
@@ -211,24 +211,27 @@ final class DisplayPortCalculator {
     }
 
     /**
      * This class implements the variation with a small fixed-size margin with velocity bias.
      * In this variation, the default margins are pretty small relative to the view size, but
      * they are affected by the panning velocity. Specifically, if we are panning on one axis,
      * we remove the margins on the other axis because we are likely axis-locked. Also once
      * we are panning in one direction above a certain threshold velocity, we shift the buffer
-     * so that it is entirely in the direction of the pan.
+     * so that it is almost entirely in the direction of the pan, with a little bit in the
+     * reverse direction.
      */
     private static class VelocityBiasStrategy implements DisplayPortStrategy {
         // The length of each axis of the display port will be the corresponding view length
         // multiplied by this factor.
-        private static final float SIZE_MULTIPLIER = 1.2f;
+        private static final float SIZE_MULTIPLIER = 1.5f;
         // The velocity above which we apply the velocity bias
         private static final float VELOCITY_THRESHOLD = GeckoAppShell.getDpi() / 32f;
+        // How much of the buffer to keep in the reverse direction of the velocity
+        private static final float REVERSE_BUFFER = 0.2f;
 
         public DisplayPortMetrics calculate(ImmutableViewportMetrics metrics, PointF velocity) {
             float displayPortWidth = metrics.getWidth() * SIZE_MULTIPLIER;
             float displayPortHeight = metrics.getHeight() * SIZE_MULTIPLIER;
 
             // but if we're panning on one axis, set the margins for the other axis to zero since we are likely
             // axis locked and won't be displaying that extra area.
             if (Math.abs(velocity.x) > VELOCITY_THRESHOLD && FloatUtils.fuzzyEquals(velocity.y, 0)) {
@@ -244,31 +247,33 @@ final class DisplayPortCalculator {
             float horizontalBuffer = displayPortWidth - metrics.getWidth();
             float verticalBuffer = displayPortHeight - metrics.getHeight();
 
             // if we're panning above the VELOCITY_THRESHOLD on an axis, apply the margin so that it
             // is entirely in the direction of panning. Otherwise, split the margin evenly on both sides of
             // the display port.
             RectF margins = new RectF();
             if (velocity.x > VELOCITY_THRESHOLD) {
-                margins.right = horizontalBuffer;
+                margins.left = horizontalBuffer * REVERSE_BUFFER;
             } else if (velocity.x < -VELOCITY_THRESHOLD) {
-                margins.left = horizontalBuffer;
+                margins.left = horizontalBuffer * (1.0f - REVERSE_BUFFER);
             } else {
                 margins.left = horizontalBuffer / 2.0f;
-                margins.right = horizontalBuffer - margins.left;
             }
+            margins.right = horizontalBuffer - margins.left;
+
             if (velocity.y > VELOCITY_THRESHOLD) {
-                margins.bottom = verticalBuffer;
+                margins.top = verticalBuffer * REVERSE_BUFFER;
             } else if (velocity.y < -VELOCITY_THRESHOLD) {
-                margins.top = verticalBuffer;
+                margins.top = verticalBuffer * (1.0f - REVERSE_BUFFER);
             } else {
                 margins.top = verticalBuffer / 2.0f;
-                margins.bottom = verticalBuffer - margins.top;
             }
+            margins.bottom = verticalBuffer - margins.top;
+
             // and finally shift the margins to account for page bounds
             margins = shiftMarginsForPageBounds(margins, metrics);
 
             return new DisplayPortMetrics(metrics.viewportRectLeft - margins.left,
                     metrics.viewportRectTop - margins.top,
                     metrics.viewportRectRight + margins.right,
                     metrics.viewportRectBottom + margins.bottom,
                     metrics.zoomFactor);
--- a/testing/marionette/client/marionette/marionette.py
+++ b/testing/marionette/client/marionette/marionette.py
@@ -65,17 +65,17 @@ class HTMLElement(object):
 
     def find_element(self, method, target):
         return self.marionette.find_element(method, target, self.id)
 
     def find_elements(self, method, target):
         return self.marionette.find_elements(method, target, self.id)
 
     def get_attribute(self, attribute):
-        return self.marionette._send_message('getElementAttribute', 'value', element=self.id, name=attribute)
+        return self.marionette._send_message('getAttributeValue', 'value', element=self.id, name=attribute)
 
     def click(self):
         return self.marionette._send_message('clickElement', 'ok', element=self.id)
 
     def text(self):
         return self.marionette._send_message('getElementText', 'value', element=self.id)
 
     def send_keys(self, string):
--- a/testing/marionette/client/marionette/tests/unit/test_click.py
+++ b/testing/marionette/client/marionette/tests/unit/test_click.py
@@ -39,8 +39,34 @@ from marionette_test import MarionetteTe
 class TestClick(MarionetteTestCase):
     def test_click(self):
         test_html = self.marionette.absolute_url("test.html")
         self.marionette.navigate(test_html)
         link = self.marionette.find_element("id", "mozLink")
         link.click()
         self.assertEqual("Clicked", self.marionette.execute_script("return document.getElementById('mozLink').innerHTML;"))
 
+class TestClickChrome(MarionetteTestCase):
+    def setUp(self):
+        MarionetteTestCase.setUp(self)
+        self.marionette.set_context("chrome")
+        self.win = self.marionette.get_window()
+        #need to get the file:// path for xul
+        unit = os.path.abspath(os.path.join(os.path.realpath(__file__), os.path.pardir))
+        tests = os.path.abspath(os.path.join(unit, os.path.pardir))
+        mpath = os.path.abspath(os.path.join(tests, os.path.pardir))
+        xul = "file://" + os.path.join(mpath, "www", "test.xul")
+        self.marionette.execute_script("window.open('" + xul +"', '_blank', 'chrome,centerscreen');")
+
+    def tearDown(self):
+        self.marionette.execute_script("window.close();")
+        self.marionette.switch_to_window(self.win)
+        MarionetteTestCase.tearDown(self)
+
+    def test_click(self):
+        wins = self.marionette.get_windows()
+        wins.remove(self.win)
+        newWin = wins.pop()
+        self.marionette.switch_to_window(newWin)
+        box = self.marionette.find_element("id", "testBox")
+        self.assertFalse(self.marionette.execute_script("return arguments[0].checked;", [box]))
+        box.click()
+        self.assertTrue(self.marionette.execute_script("return arguments[0].checked;", [box]))
new file mode 100644
--- /dev/null
+++ b/testing/marionette/client/marionette/tests/unit/test_elementState.py
@@ -0,0 +1,86 @@
+# ***** 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 Marionette Client. 
+# 
+# The Initial Developer of the Original Code is 
+#   Mozilla Foundation. 
+# Portions created by the Initial Developer are Copyright (C) 2011
+# the Initial Developer. All Rights Reserved. 
+# 
+# Contributor(s): 
+# 
+# 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 ***** 
+
+import os
+from marionette_test import MarionetteTestCase
+
+class TestState(MarionetteTestCase):
+    def test_isEnabled(self):
+        test_html = self.marionette.absolute_url("test.html")
+        self.marionette.navigate(test_html)
+        l = self.marionette.find_element("name", "myCheckBox")
+        self.assertTrue(l.enabled())
+        self.marionette.execute_script("arguments[0].disabled = true;", [l])
+        self.assertFalse(l.enabled())
+
+    def test_isDisplayed(self):
+        test_html = self.marionette.absolute_url("test.html")
+        self.marionette.navigate(test_html)
+        l = self.marionette.find_element("name", "myCheckBox")
+        self.assertTrue(l.displayed())
+        self.marionette.execute_script("arguments[0].hidden = true;", [l])
+        self.assertFalse(l.displayed())
+
+class TestStateChrome(MarionetteTestCase):
+    def setUp(self):
+        MarionetteTestCase.setUp(self)
+        self.marionette.set_context("chrome")
+        self.win = self.marionette.get_window()
+        #need to get the file:// path for xul
+        unit = os.path.abspath(os.path.join(os.path.realpath(__file__), os.path.pardir))
+        tests = os.path.abspath(os.path.join(unit, os.path.pardir))
+        mpath = os.path.abspath(os.path.join(tests, os.path.pardir))
+        xul = "file://" + os.path.join(mpath, "www", "test.xul")
+        self.marionette.execute_script("window.open('" + xul +"', '_blank', 'chrome,centerscreen');")
+
+    def tearDown(self):
+        self.marionette.execute_script("window.close();")
+        self.marionette.switch_to_window(self.win)
+        MarionetteTestCase.tearDown(self)
+
+    def test_isEnabled(self):
+        l = self.marionette.find_element("id", "textInput")
+        self.assertTrue(l.enabled())
+        self.marionette.execute_script("arguments[0].disabled = true;", [l])
+        self.assertFalse(l.enabled())
+        self.marionette.execute_script("arguments[0].disabled = false;", [l])
+
+    def test_isDisplayed(self):
+        l = self.marionette.find_element("id", "textInput")
+        self.assertTrue(l.displayed())
+        self.marionette.execute_script("arguments[0].hidden = true;", [l])
+        self.assertFalse(l.displayed())
+        self.marionette.execute_script("arguments[0].hidden = false;", [l])
+
--- a/testing/marionette/client/marionette/tests/unit/test_findelement.py
+++ b/testing/marionette/client/marionette/tests/unit/test_findelement.py
@@ -40,73 +40,90 @@ from errors import NoSuchElementExceptio
 
 class TestElements(MarionetteTestCase):
     def test_id(self):
         test_html = self.marionette.absolute_url("test.html")
         self.marionette.navigate(test_html)
         el = self.marionette.execute_script("return window.document.getElementById('mozLink');")
         found_el = self.marionette.find_element("id", "mozLink")
         self.assertEqual(HTMLElement, type(found_el))
-        self.assertTrue(el.id, found_el.id)
+        self.assertEqual(el.id, found_el.id)
+
+    def test_child_element(self):
+        test_html = self.marionette.absolute_url("test.html")
+        self.marionette.navigate(test_html)
+        el = self.marionette.find_element("id", "divLink")
+        div = self.marionette.find_element("id", "testDiv")
+        found_el = div.find_element("tag name", "a")
+        self.assertEqual(HTMLElement, type(found_el))
+        self.assertEqual(el.id, found_el.id)
+
+    def test_child_elements(self):
+        test_html = self.marionette.absolute_url("test.html")
+        self.marionette.navigate(test_html)
+        el = self.marionette.find_element("id", "divLink2")
+        div = self.marionette.find_element("id", "testDiv")
+        found_els = div.find_elements("tag name", "a")
+        self.assertTrue(el.id in [found_el.id for found_el in found_els])
 
     def test_tag_name(self):
         test_html = self.marionette.absolute_url("test.html")
         self.marionette.navigate(test_html)
         el = self.marionette.execute_script("return window.document.getElementsByTagName('body')[0];")
         found_el = self.marionette.find_element("tag name", "body")
         self.assertEqual(HTMLElement, type(found_el))
-        self.assertTrue(el.id, found_el.id)
+        self.assertEqual(el.id, found_el.id)
 
     def test_class_name(self):
         test_html = self.marionette.absolute_url("test.html")
         self.marionette.navigate(test_html)
         el = self.marionette.execute_script("return window.document.getElementsByClassName('linkClass')[0];")
         found_el = self.marionette.find_element("class name", "linkClass")
         self.assertEqual(HTMLElement, type(found_el));
-        self.assertTrue(el.id, found_el.id)
+        self.assertEqual(el.id, found_el.id)
 
     def test_name(self):
         test_html = self.marionette.absolute_url("test.html")
         self.marionette.navigate(test_html)
         el = self.marionette.execute_script("return window.document.getElementsByName('myInput')[0];")
         found_el = self.marionette.find_element("name", "myInput")
         self.assertEqual(HTMLElement, type(found_el))
-        self.assertTrue(el.id, found_el.id)
+        self.assertEqual(el.id, found_el.id)
     
     def test_selector(self):
         test_html = self.marionette.absolute_url("test.html")
         self.marionette.navigate(test_html)
         el = self.marionette.execute_script("return window.document.getElementById('testh1');")
         found_el = self.marionette.find_element("css selector", "h1")
         self.assertEqual(HTMLElement, type(found_el))
-        self.assertTrue(el.id, found_el.id)
+        self.assertEqual(el.id, found_el.id)
 
     def test_link_text(self):
         test_html = self.marionette.absolute_url("test.html")
         self.marionette.navigate(test_html)
         el = self.marionette.execute_script("return window.document.getElementById('mozLink');")
         found_el = self.marionette.find_element("link text", "Click me!")
         self.assertEqual(HTMLElement, type(found_el))
-        self.assertTrue(el.id, found_el.id)
+        self.assertEqual(el.id, found_el.id)
 
     def test_partial_link_text(self):
         test_html = self.marionette.absolute_url("test.html")
         self.marionette.navigate(test_html)
         el = self.marionette.execute_script("return window.document.getElementById('mozLink');")
         found_el = self.marionette.find_element("partial link text", "Click m")
         self.assertEqual(HTMLElement, type(found_el))
-        self.assertTrue(el.id, found_el.id)
+        self.assertEqual(el.id, found_el.id)
 
     def test_xpath(self):
         test_html = self.marionette.absolute_url("test.html")
         self.marionette.navigate(test_html)
         el = self.marionette.execute_script("return window.document.getElementById('mozLink');")
         found_el = self.marionette.find_element("xpath", "id('mozLink')")
         self.assertEqual(HTMLElement, type(found_el))
-        self.assertTrue(el.id, found_el.id)
+        self.assertEqual(el.id, found_el.id)
 
     def test_not_found(self):
         test_html = self.marionette.absolute_url("test.html")
         self.marionette.navigate(test_html)
         self.assertRaises(NoSuchElementException, self.marionette.find_element, "id", "I'm not on the page")
 
     def test_timeout(self):
         test_html = self.marionette.absolute_url("test.html")
@@ -115,43 +132,68 @@ class TestElements(MarionetteTestCase):
         self.assertTrue(True, self.marionette.set_search_timeout(4000))
         self.marionette.navigate(test_html)
         self.assertEqual(HTMLElement, type(self.marionette.find_element("id", "newDiv")))
 
 class TestElementsChrome(MarionetteTestCase):
     def setUp(self):
         MarionetteTestCase.setUp(self)
         self.marionette.set_context("chrome")
+        self.win = self.marionette.get_window()
+        #need to get the file:// path for xul
+        unit = os.path.abspath(os.path.join(os.path.realpath(__file__), os.path.pardir))
+        tests = os.path.abspath(os.path.join(unit, os.path.pardir))
+        mpath = os.path.abspath(os.path.join(tests, os.path.pardir))
+        xul = "file://" + os.path.join(mpath, "www", "test.xul")
+        self.marionette.execute_script("window.open('" + xul +"', '_blank', 'chrome,centerscreen');")
+
+    def tearDown(self):
+        self.marionette.execute_script("window.close();")
+        self.marionette.switch_to_window(self.win)
+        MarionetteTestCase.tearDown(self)
 
     def test_id(self):
-        el = self.marionette.execute_script("return window.document.getElementById('main-window');")
-        found_el = self.marionette.find_element("id", "main-window")
+        el = self.marionette.execute_script("return window.document.getElementById('textInput');")
+        found_el = self.marionette.find_element("id", "textInput")
         self.assertEqual(HTMLElement, type(found_el))
-        self.assertTrue(el.id, found_el.id)
+        self.assertEqual(el.id, found_el.id)
+
+    def test_child_element(self):
+        el = self.marionette.find_element("id", "textInput")
+        parent = self.marionette.find_element("id", "things")
+        found_el = parent.find_element("tag name", "textbox")
+        self.assertEqual(HTMLElement, type(found_el))
+        self.assertEqual(el.id, found_el.id)
+
+    def test_child_elements(self):
+        el = self.marionette.find_element("id", "textInput3")
+        parent = self.marionette.find_element("id", "things")
+        found_els = parent.find_elements("tag name", "textbox")
+        self.assertTrue(el.id in [found_el.id for found_el in found_els])
 
     def test_tag_name(self):
-        el = self.marionette.execute_script("return window.document.getElementsByTagName('window')[0];")
-        found_el = self.marionette.find_element("tag name", "window")
+        el = self.marionette.execute_script("return window.document.getElementsByTagName('vbox')[0];")
+        found_el = self.marionette.find_element("tag name", "vbox")
         self.assertEqual(HTMLElement, type(found_el))
-        self.assertTrue(el.id, found_el.id)
+        self.assertEqual(el.id, found_el.id)
 
     def test_class_name(self):
-        el = self.marionette.execute_script("return window.document.getElementsByClassName('editBookmarkPanelHeaderButton')[0];")
-        found_el = self.marionette.find_element("class name", "editBookmarkPanelHeaderButton")
+        el = self.marionette.execute_script("return window.document.getElementsByClassName('asdf')[0];")
+        found_el = self.marionette.find_element("class name", "asdf")
         self.assertEqual(HTMLElement, type(found_el));
-        self.assertTrue(el.id, found_el.id)
+        self.assertEqual(el.id, found_el.id)
 
     def test_xpath(self):
-        el = self.marionette.execute_script("return window.document.getElementById('main-window');")
-        found_el = self.marionette.find_element("xpath", "id('main-window')")
+        el = self.marionette.execute_script("return window.document.getElementById('testBox');")
+        found_el = self.marionette.find_element("xpath", "id('testBox')")
         self.assertEqual(HTMLElement, type(found_el));
-        self.assertTrue(el.id, found_el.id)
+        self.assertEqual(el.id, found_el.id)
 
     def test_not_found(self):
         self.assertRaises(NoSuchElementException, self.marionette.find_element, "id", "I'm not on the page")
 
 
     def test_timeout(self):
         self.assertRaises(NoSuchElementException, self.marionette.find_element, "id", "myid")
         self.assertTrue(True, self.marionette.set_search_timeout(4000))
-        self.marionette.execute_script("window.setTimeout(function() {var b = window.document.createElement('button'); b.id = 'myid'; document.getElementById('main-window').appendChild(b);}, 1000)")
+        self.marionette.execute_script("window.setTimeout(function() {var b = window.document.createElement('button'); b.id = 'myid'; document.getElementById('things').appendChild(b);}, 1000)")
         self.assertEqual(HTMLElement, type(self.marionette.find_element("id", "myid")))
-        self.marionette.execute_script("window.document.getElementById('main-window').removeChild(window.document.getElementById('myid'));")
+        self.marionette.execute_script("window.document.getElementById('things').removeChild(window.document.getElementById('myid'));")
new file mode 100644
--- /dev/null
+++ b/testing/marionette/client/marionette/tests/unit/test_getattr.py
@@ -0,0 +1,67 @@
+# ***** 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 Marionette Client. 
+# 
+# The Initial Developer of the Original Code is 
+#   Mozilla Foundation. 
+# Portions created by the Initial Developer are Copyright (C) 2011
+# the Initial Developer. All Rights Reserved. 
+# 
+# Contributor(s): 
+# 
+# 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 ***** 
+
+import os
+from marionette_test import MarionetteTestCase
+
+class TestGetAttribute(MarionetteTestCase):
+    def test_getAttribute(self):
+        test_html = self.marionette.absolute_url("test.html")
+        self.marionette.navigate(test_html)
+        l = self.marionette.find_element("id", "mozLink")
+        self.assertEqual("mozLink", l.get_attribute("id"))
+
+class TestGetAttributeChrome(MarionetteTestCase):
+    def setUp(self):
+        MarionetteTestCase.setUp(self)
+        self.marionette.set_context("chrome")
+        self.win = self.marionette.get_window()
+        #need to get the file:// path for xul
+        unit = os.path.abspath(os.path.join(os.path.realpath(__file__), os.path.pardir))
+        tests = os.path.abspath(os.path.join(unit, os.path.pardir))
+        mpath = os.path.abspath(os.path.join(tests, os.path.pardir))
+        xul = "file://" + os.path.join(mpath, "www", "test.xul")
+        self.marionette.execute_script("window.open('" + xul +"', '_blank', 'chrome,centerscreen');")
+
+    def tearDown(self):
+        self.marionette.execute_script("window.close();")
+        self.marionette.switch_to_window(self.win)
+        MarionetteTestCase.tearDown(self)
+
+    def test_getAttribute(self):
+        el = self.marionette.execute_script("return window.document.getElementById('textInput');")
+        found_el = self.marionette.find_element("id", "textInput")
+        self.assertEqual(el.get_attribute("id"), "textInput")
+
new file mode 100644
--- /dev/null
+++ b/testing/marionette/client/marionette/tests/unit/test_selected.py
@@ -0,0 +1,73 @@
+# ***** 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 Marionette Client. 
+# 
+# The Initial Developer of the Original Code is 
+#   Mozilla Foundation. 
+# Portions created by the Initial Developer are Copyright (C) 2011
+# the Initial Developer. All Rights Reserved. 
+# 
+# Contributor(s): 
+# 
+# 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 ***** 
+
+import os
+from marionette_test import MarionetteTestCase
+
+class TestSelected(MarionetteTestCase):
+    def test_selected(self):
+        test_html = self.marionette.absolute_url("test.html")
+        self.marionette.navigate(test_html)
+        box = self.marionette.find_element("name", "myCheckBox")
+        self.assertFalse(box.selected())
+        box.click()
+        self.assertTrue(box.selected())
+
+class TestSelectedChrome(MarionetteTestCase):
+    def setUp(self):
+        MarionetteTestCase.setUp(self)
+        self.marionette.set_context("chrome")
+        self.win = self.marionette.get_window()
+        #need to get the file:// path for xul
+        unit = os.path.abspath(os.path.join(os.path.realpath(__file__), os.path.pardir))
+        tests = os.path.abspath(os.path.join(unit, os.path.pardir))
+        mpath = os.path.abspath(os.path.join(tests, os.path.pardir))
+        xul = "file://" + os.path.join(mpath, "www", "test.xul")
+        self.marionette.execute_script("window.open('" + xul +"', '_blank', 'chrome,centerscreen');")
+
+    def tearDown(self):
+        self.marionette.execute_script("window.close();")
+        self.marionette.switch_to_window(self.win)
+        MarionetteTestCase.tearDown(self)
+
+    def test_selected(self):
+        wins = self.marionette.get_windows()
+        wins.remove(self.win)
+        newWin = wins.pop()
+        self.marionette.switch_to_window(newWin)
+        box = self.marionette.find_element("id", "testBox")
+        self.assertFalse(box.selected())
+        self.assertFalse(self.marionette.execute_script("arguments[0].checked = true;", [box]))
+        self.assertTrue(box.selected())
new file mode 100644
--- /dev/null
+++ b/testing/marionette/client/marionette/tests/unit/test_text.py
@@ -0,0 +1,105 @@
+# ***** 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 Marionette Client. 
+# 
+# The Initial Developer of the Original Code is 
+#   Mozilla Foundation. 
+# Portions created by the Initial Developer are Copyright (C) 2011
+# the Initial Developer. All Rights Reserved. 
+# 
+# Contributor(s): 
+# 
+# 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 ***** 
+
+import os
+from marionette_test import MarionetteTestCase
+
+class TestText(MarionetteTestCase):
+    def test_getText(self):
+        test_html = self.marionette.absolute_url("test.html")
+        self.marionette.navigate(test_html)
+        l = self.marionette.find_element("id", "mozLink")
+        self.assertEqual("Click me!", l.text())
+
+    def test_clearText(self):
+        test_html = self.marionette.absolute_url("test.html")
+        self.marionette.navigate(test_html)
+        l = self.marionette.find_element("name", "myInput")
+        self.assertEqual("asdf", self.marionette.execute_script("return arguments[0].value;", [l]))
+        l.clear()
+        self.assertEqual("", self.marionette.execute_script("return arguments[0].value;", [l]))
+
+    def test_sendKeys(self):
+        test_html = self.marionette.absolute_url("test.html")
+        self.marionette.navigate(test_html)
+        l = self.marionette.find_element("name", "myInput")
+        self.assertEqual("asdf", self.marionette.execute_script("return arguments[0].value;", [l]))
+        l.send_keys("o")
+        self.assertEqual("asdfo", self.marionette.execute_script("return arguments[0].value;", [l]))
+
+class TestTextChrome(MarionetteTestCase):
+    def setUp(self):
+        MarionetteTestCase.setUp(self)
+        self.marionette.set_context("chrome")
+        self.win = self.marionette.get_window()
+        #need to get the file:// path for xul
+        unit = os.path.abspath(os.path.join(os.path.realpath(__file__), os.path.pardir))
+        tests = os.path.abspath(os.path.join(unit, os.path.pardir))
+        mpath = os.path.abspath(os.path.join(tests, os.path.pardir))
+        xul = "file://" + os.path.join(mpath, "www", "test.xul")
+        self.marionette.execute_script("window.open('" + xul +"', '_blank', 'chrome,centerscreen');")
+
+    def tearDown(self):
+        self.marionette.execute_script("window.close();")
+        self.marionette.switch_to_window(self.win)
+        MarionetteTestCase.tearDown(self)
+
+    def test_getText(self):
+        wins = self.marionette.get_windows()
+        wins.remove(self.win)
+        newWin = wins.pop()
+        self.marionette.switch_to_window(newWin)
+        box = self.marionette.find_element("id", "textInput")
+        self.assertEqual("test", box.text())
+
+    def test_clearText(self):
+        wins = self.marionette.get_windows()
+        wins.remove(self.win)
+        newWin = wins.pop()
+        self.marionette.switch_to_window(newWin)
+        box = self.marionette.find_element("id", "textInput")
+        self.assertEqual("test", box.text())
+        box.clear()
+        self.assertEqual("", box.text())
+
+    def test_sendKeys(self):
+        wins = self.marionette.get_windows()
+        wins.remove(self.win)
+        newWin = wins.pop()
+        self.marionette.switch_to_window(newWin)
+        box = self.marionette.find_element("id", "textInput")
+        self.assertEqual("test", box.text())
+        box.send_keys("at")
+        self.assertEqual("attest", box.text())
--- a/testing/marionette/client/marionette/tests/unit/unit-tests.ini
+++ b/testing/marionette/client/marionette/tests/unit/unit-tests.ini
@@ -1,10 +1,18 @@
 [test_click.py]
 b2g = false
+[test_selected.py]
+b2g = false
+[test_getattr.py]
+b2g = false
+[test_elementState.py]
+b2g = false
+[test_text.py]
+b2g = false
 
 [test_log.py]
 [test_execute_async_script.py]
 [test_execute_script.py]
 [test_simpletest_fail.js]
 [test_findelement.py]
 b2g = false
 
--- a/testing/marionette/client/marionette/www/test.html
+++ b/testing/marionette/client/marionette/www/test.html
@@ -16,12 +16,16 @@
       document.body.appendChild(newDiv);
     }
     function clicked() {
       var link = document.getElementById("mozLink");
       link.innerHTML = "Clicked";
     }
   </script>
   <a href="#" id="mozLink" class="linkClass" onclick="clicked()">Click me!</a>
-  <a href="#" id="mozLink" class="linkClass" onclick="clicked()">Click me!</a>
-  <input name="myInput" type="text" />
+  <div id="testDiv">
+    <a href="#" id="divLink" class="linkClass" onclick="clicked()">Div click me!</a>
+    <a href="#" id="divLink2" class="linkClass" onclick="clicked()">Div click me!</a>
+  </div>
+  <input name="myInput" type="text" value="asdf"/>
+  <input name="myCheckBox" type="checkbox" />
 </body>
 </html> 
new file mode 100644
--- /dev/null
+++ b/testing/marionette/client/marionette/www/test.xul
@@ -0,0 +1,15 @@
+<?xml version="1.0"?>
+<!DOCTYPE window [
+]>
+
+<dialog id="dia"
+            xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+
+  <vbox id="things">
+    <checkbox id="testBox"  label="box" />
+    <textbox id="textInput"  size="6" value="test" label="input" />
+    <textbox id="textInput2"  size="6" value="test" label="input" />
+    <textbox id="textInput3" class="asdf" size="6" value="test" label="input" />
+  </vbox>
+     
+</dialog>