Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e526f14e authored by John Reck's avatar John Reck Committed by Android (Google) Code Review
Browse files

Merge "Show WebView layers in hierarchyviewer"

parents e446e6c9 926cf566
Loading
Loading
Loading
Loading
+39 −0
Original line number Diff line number Diff line
@@ -255,6 +255,35 @@ public class ViewDebug {
        boolean retrieveReturn() default false;
    }

    /**
     * Allows a View to inject custom children into HierarchyViewer. For example,
     * WebView uses this to add its internal layer tree as a child to itself
     * @hide
     */
    public interface HierarchyHandler {
        /**
         * Dumps custom children to hierarchy viewer.
         * See {@link ViewDebug#dumpViewWithProperties(Context, View, BufferedWriter, int)}
         * for the format
         *
         * An empty implementation should simply do nothing
         *
         * @param out The output writer
         * @param level The indentation level
         */
        public void dumpViewHierarchyWithProperties(BufferedWriter out, int level);

        /**
         * Returns a View to enable grabbing screenshots from custom children
         * returned in dumpViewHierarchyWithProperties.
         *
         * @param className The className of the view to find
         * @param hashCode The hashCode of the view to find
         * @return the View to capture from, or null if not found
         */
        public View findHierarchyView(String className, int hashCode);
    }

    private static HashMap<Class<?>, Method[]> mCapturedViewMethodsForClasses = null;
    private static HashMap<Class<?>, Field[]> mCapturedViewFieldsForClasses = null;

@@ -759,6 +788,13 @@ public class ViewDebug {
            } else if (isRequestedView(view, className, hashCode)) {
                return view;
            }
            if (view instanceof HierarchyHandler) {
                final View found = ((HierarchyHandler)view)
                        .findHierarchyView(className, hashCode);
                if (found != null) {
                    return found;
                }
            }
        }

        return null;
@@ -783,6 +819,9 @@ public class ViewDebug {
                dumpViewWithProperties(context, view, out, level + 1);
            }
        }
        if (group instanceof HierarchyHandler) {
            ((HierarchyHandler)group).dumpViewHierarchyWithProperties(out, level + 1);
        }
    }

    private static boolean dumpViewWithProperties(Context context, View view,
+9 −1
Original line number Diff line number Diff line
@@ -16,7 +16,6 @@
package android.webkit;

import android.graphics.Point;
import android.graphics.Region;
import android.webkit.WebViewCore.DrawData;

import java.io.DataInputStream;
@@ -68,6 +67,15 @@ class ViewStateSerializer {
        return draw;
    }

    public static void dumpLayerHierarchy(int baseLayer, OutputStream out, int level) {
        nativeDumpLayerHierarchy(baseLayer, level, out,
                new byte[WORKING_STREAM_STORAGE]);
    }


    private static native void nativeDumpLayerHierarchy(int baseLayer, int level,
            OutputStream out, byte[] storage);

    private static native boolean nativeSerializeViewState(int baseLayer,
            OutputStream stream, byte[] storage);

+27 −2
Original line number Diff line number Diff line
@@ -35,8 +35,8 @@ import android.util.Log;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewDebug;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.view.ViewTreeObserver;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityNodeInfo;
@@ -44,6 +44,7 @@ import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputConnection;
import android.widget.AbsoluteLayout;

import java.io.BufferedWriter;
import java.io.File;
import java.util.Map;

@@ -263,7 +264,7 @@ import java.util.Map;
@Widget
public class WebView extends AbsoluteLayout
        implements ViewTreeObserver.OnGlobalFocusChangeListener,
        ViewGroup.OnHierarchyChangeListener {
        ViewGroup.OnHierarchyChangeListener, ViewDebug.HierarchyHandler {

    private static final String LOGTAG = "webview_proxy";

@@ -1004,6 +1005,7 @@ public class WebView extends AbsoluteLayout
     *
     * @return the current scale
     */
    @ViewDebug.ExportedProperty(category = "webview")
    public float getScale() {
        checkThread();
        return mProvider.getScale();
@@ -1094,6 +1096,7 @@ public class WebView extends AbsoluteLayout
     *
     * @return the URL for the current page
     */
    @ViewDebug.ExportedProperty(category = "webview")
    public String getUrl() {
        checkThread();
        return mProvider.getUrl();
@@ -1108,6 +1111,7 @@ public class WebView extends AbsoluteLayout
     *
     * @return the URL that was originally requested for the current page
     */
    @ViewDebug.ExportedProperty(category = "webview")
    public String getOriginalUrl() {
        checkThread();
        return mProvider.getOriginalUrl();
@@ -1119,6 +1123,7 @@ public class WebView extends AbsoluteLayout
     *
     * @return the title for the current page
     */
    @ViewDebug.ExportedProperty(category = "webview")
    public String getTitle() {
        checkThread();
        return mProvider.getTitle();
@@ -1161,6 +1166,7 @@ public class WebView extends AbsoluteLayout
     *
     * @return the height of the HTML content
     */
    @ViewDebug.ExportedProperty(category = "webview")
    public int getContentHeight() {
        checkThread();
        return mProvider.getContentHeight();
@@ -1172,6 +1178,7 @@ public class WebView extends AbsoluteLayout
     * @return the width of the HTML content
     * @hide
     */
    @ViewDebug.ExportedProperty(category = "webview")
    public int getContentWidth() {
        return mProvider.getContentWidth();
    }
@@ -1652,6 +1659,24 @@ public class WebView extends AbsoluteLayout
        mProvider.debugDump();
    }

    /**
     * See {@link ViewDebug.HierarchyHandler#dumpViewHierarchyWithProperties(String, int)}
     * @hide
     */
    @Override
    public void dumpViewHierarchyWithProperties(BufferedWriter out, int level) {
        mProvider.dumpViewHierarchyWithProperties(out, level);
    }

    /**
     * See {@link ViewDebug.HierarchyHandler#findHierarchyView(String, int)}
     * @hide
     */
    @Override
    public View findHierarchyView(String className, int hashCode) {
        return mProvider.findHierarchyView(className, hashCode);
    }

    //-------------------------------------------------------------------------
    // Interface for WebView providers
    //-------------------------------------------------------------------------
+53 −0
Original line number Diff line number Diff line
@@ -117,6 +117,8 @@ import android.widget.Toast;

import junit.framework.Assert;

import java.io.BufferedWriter;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
@@ -132,6 +134,7 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Vector;
import java.util.concurrent.CountDownLatch;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@@ -8594,6 +8597,54 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc
        WebViewCore.setShouldMonitorWebCoreThread();
    }

    @Override
    public void dumpViewHierarchyWithProperties(BufferedWriter out, int level) {
        int layer = getBaseLayer();
        if (layer != 0) {
            try {
                ByteArrayOutputStream stream = new ByteArrayOutputStream();
                ViewStateSerializer.dumpLayerHierarchy(layer, stream, level);
                stream.close();
                byte[] buf = stream.toByteArray();
                out.write(new String(buf, "ascii"));
            } catch (IOException e) {}
        }
    }

    @Override
    public View findHierarchyView(String className, int hashCode) {
        if (mNativeClass == 0) return null;
        Picture pic = new Picture();
        if (!nativeDumpLayerContentToPicture(mNativeClass, className, hashCode, pic)) {
            return null;
        }
        return new PictureWrapperView(getContext(), pic, mWebView);
    }

    private static class PictureWrapperView extends View {
        Picture mPicture;
        WebView mWebView;

        public PictureWrapperView(Context context, Picture picture, WebView parent) {
            super(context);
            mPicture = picture;
            mWebView = parent;
            setWillNotDraw(false);
            setRight(mPicture.getWidth());
            setBottom(mPicture.getHeight());
        }

        @Override
        protected void onDraw(Canvas canvas) {
            canvas.drawPicture(mPicture);
        }

        @Override
        public boolean post(Runnable action) {
            return mWebView.post(action);
        }
    }

    private native void     nativeCreate(int ptr, String drawableDir, boolean isHighEndGfx);
    private native void     nativeDebugDump();
    private static native void nativeDestroy(int ptr);
@@ -8614,6 +8665,8 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc
            int scrollingLayer);
    private native int      nativeGetBaseLayer(int nativeInstance);
    private native void     nativeCopyBaseContentToPicture(Picture pict);
    private native boolean     nativeDumpLayerContentToPicture(int nativeInstance,
            String className, int layerId, Picture pict);
    private native boolean  nativeHasContent();
    private native void     nativeStopGL(int ptr);
    private native void     nativeDiscardAllTextures();
+5 −0
Original line number Diff line number Diff line
@@ -37,6 +37,7 @@ import android.view.inputmethod.InputConnection;
import android.webkit.WebView.HitTestResult;
import android.webkit.WebView.PictureListener;

import java.io.BufferedWriter;
import java.io.File;
import java.util.Map;

@@ -238,6 +239,10 @@ public interface WebViewProvider {

    public void debugDump();

    public void dumpViewHierarchyWithProperties(BufferedWriter out, int level);

    public View findHierarchyView(String className, int hashCode);

    //-------------------------------------------------------------------------
    // Provider glue methods
    //-------------------------------------------------------------------------