Bug 1335895 - part 33: Update FennecNativeDriver.java so robocop tests work with new dynamic toolbar r=jchen,kats draft
authorRandall Barker <rbarker@mozilla.com>
Sat, 01 Apr 2017 15:47:35 -0700
changeset 558775 b17c5dac5baf5fb8f377c312f8525f3cd3bb4104
parent 558774 fa6a016c1105788c4db7b42f43165742c9306984
child 558776 be93941d78c6f2f55a29393f586805e9ef4061af
push id52941
push userbmo:rbarker@mozilla.com
push dateFri, 07 Apr 2017 23:43:33 +0000
reviewersjchen, kats
bugs1335895
milestone55.0a1
Bug 1335895 - part 33: Update FennecNativeDriver.java so robocop tests work with new dynamic toolbar r=jchen,kats
mobile/android/tests/browser/robocop/src/org/mozilla/gecko/FennecNativeDriver.java
--- a/mobile/android/tests/browser/robocop/src/org/mozilla/gecko/FennecNativeDriver.java
+++ b/mobile/android/tests/browser/robocop/src/org/mozilla/gecko/FennecNativeDriver.java
@@ -12,30 +12,33 @@ import java.io.FileOutputStream;
 import java.io.FileReader;
 import java.io.FileWriter;
 import java.io.IOException;
 import java.io.PrintWriter;
 import java.nio.IntBuffer;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.lang.StringBuffer;
+import java.lang.Math;
 
+import org.mozilla.gecko.GeckoThread;
 import org.mozilla.gecko.gfx.LayerView;
 import org.mozilla.gecko.gfx.PanningPerfAPI;
 import org.mozilla.gecko.util.BundleEventListener;
 import org.mozilla.gecko.util.EventCallback;
 import org.mozilla.gecko.util.GeckoBundle;
 
 import android.app.Activity;
 import android.util.Log;
 import android.view.View;
 
 import com.robotium.solo.Solo;
 
-public class FennecNativeDriver implements Driver {
+public class FennecNativeDriver implements Driver, LayerView.GetPixelsResult {
     private static final int FRAME_TIME_THRESHOLD = 25;     // allow 25ms per frame (40fps)
 
     private final Activity mActivity;
     private final Solo mSolo;
     private final String mRootPath;
 
     private static String mLogFile;
     private static LogLevel mLogLevel = LogLevel.INFO;
@@ -79,16 +82,24 @@ public class FennecNativeDriver implemen
             mGeckoTop = pos[1];
             mGeckoLeft = pos[0];
             mGeckoWidth = geckoLayout.getWidth();
             mGeckoHeight = geckoLayout.getHeight();
             mGeckoInfo = true;
         } else {
             throw new RoboCopException("Unable to find view gecko_layout");
         }
+        View toolbarLayout = mActivity.findViewById(R.id.browser_chrome);
+        if (toolbarLayout != null) {
+          // Need to remove the height of the toolbar since the top part of
+          // the gecko_layout is hidden under the toolbar.
+          final int toolbarHeight = toolbarLayout.getHeight();
+          mGeckoTop += toolbarHeight;
+          mGeckoHeight -= toolbarHeight;
+        }
     }
 
     @Override
     public int getGeckoTop() {
         if (!mGeckoInfo) {
             getGeckoInfo();
         }
         return mGeckoTop;
@@ -173,29 +184,125 @@ public class FennecNativeDriver implemen
             log(LogLevel.WARN, "getSurfaceView could not find LayerView");
             for (final View v : mSolo.getViews()) {
                 log(LogLevel.WARN, "  View: " + v);
             }
         }
         return layerView;
     }
 
+    private volatile boolean mGotPixelsResult;
+    private int mPixelsWidth;
+    private int mPixelsHeight;
+    private IntBuffer mPixelsResult;
+
+    @Override
+    public void onPixelsResult(int aWidth, int aHeight, IntBuffer aPixels) {
+        synchronized (this) {
+            mPixelsWidth = aWidth;
+            mPixelsHeight = aHeight;
+            mPixelsResult = aPixels;
+            mGotPixelsResult = true;
+            notifyAll();
+        }
+    }
+
+    private static final int COLOR_DEVIATION = 3;
+
+    private boolean differentColor(final int c1, final int c2) {
+        int r1 = c1 & 0xFF;
+        int b1 = (c1 & 0xFF00) >> 8;
+        int g1 = (c1 & 0xFF0000) >> 16;
+        int r2 = c2 & 0xFF;
+        int b2 = (c2 & 0xFF00) >> 8;
+        int g2 = (c2 & 0xFF0000) >> 16;
+        return (Math.abs(r1 - r2) > COLOR_DEVIATION) ||
+               (Math.abs(g1 - g2) > COLOR_DEVIATION) ||
+               (Math.abs(b1 - b2) > COLOR_DEVIATION);
+    }
+
+    private void logPixels(final IntBuffer pixelBuffer, final int w, final int h) {
+        pixelBuffer.position(0);
+
+        int lastStart = 0xFF000000;
+        int last = 0xFF000000;
+        StringBuffer sb = null;
+        for (int y = 0; y < h; y++) {
+             for (int x = 0; x < w; x++) {
+                 int agbr = pixelBuffer.get();
+                 if ((x == 0) && (lastStart != agbr)) {
+                     sb = new StringBuffer();
+                     lastStart = agbr;
+                 }
+
+                 if ((sb != null) && differentColor(last, agbr)) {
+                     sb.append("(");
+                     int value = agbr & 0xFF;
+                     if(value < 10) sb.append("  ");
+                     else if(value < 100) sb.append(" ");
+                     sb.append(value);
+                     sb.append(",");
+                     value = (agbr & 0xFF00) >> 8;
+                     if(value < 10) sb.append("  ");
+                     else if(value < 100) sb.append(" ");
+                     sb.append(value);
+                     sb.append(",");
+                     value = (agbr & 0xFF0000) >> 16;
+                     if(value < 10) sb.append("  ");
+                     else if(value < 100) sb.append(" ");
+                     sb.append(value);
+                     sb.append(") ");
+                 }
+                 last = agbr;
+             }
+             if (sb != null) {
+                 sb.append("h:").append(h - y);
+                 log(LogLevel.INFO,sb.toString());
+                 sb = null;
+             }
+        }
+    }
+
     @Override
     public PaintedSurface getPaintedSurface() {
         final LayerView view = getSurfaceView();
         if (view == null) {
             return null;
         }
 
-        final IntBuffer pixelBuffer = view.getPixels();
+        view.getPixels(this);
+
+        synchronized (this) {
+            while (!mGotPixelsResult) {
+                try {
+                    wait();
+                } catch (InterruptedException ie) {
+                }
+            }
+        }
+
+        final IntBuffer pixelBuffer = mPixelsResult;
+        int w = mPixelsWidth;
+        int h = mPixelsHeight;
+
+        mGotPixelsResult = false;
+        mPixelsWidth = 0;
+        mPixelsHeight = 0;
+        mPixelsResult = null;
+
+
+        if ((pixelBuffer == null) || (w == 0) || (h == 0)) {
+            return null;
+        }
+
+        // This function will output a human readable log of the returned pixels to the log.
+        // logPixels(pixelBuffer, w, h);
 
         // 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);
         String mapFile = mRootPath + "/pixels.map";
 
         FileOutputStream fos = null;
         BufferedOutputStream bos = null;
         DataOutputStream dos = null;
         try {
             fos = new FileOutputStream(mapFile);