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

Commit ccb11e18 authored by Alan Viverette's avatar Alan Viverette
Browse files

Add API for specifying popup window shadows and shadow insets

BUG: 14569120
BUG: 13211941

Change-Id: Ia21596b25a0471344d42d59377074f67fce00042
parent 99bd4eab
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -918,6 +918,7 @@ package android {
    field public static final int popupAnimationStyle = 16843465; // 0x10102c9
    field public static final int popupBackground = 16843126; // 0x1010176
    field public static final int popupCharacters = 16843332; // 0x1010244
    field public static final int popupElevation = 16843918; // 0x101048e
    field public static final int popupKeyboard = 16843331; // 0x1010243
    field public static final int popupLayout = 16843323; // 0x101023b
    field public static final int popupMenuStyle = 16843520; // 0x1010300
@@ -37289,6 +37290,7 @@ package android.widget {
    method public int getAnimationStyle();
    method public android.graphics.drawable.Drawable getBackground();
    method public android.view.View getContentView();
    method public float getElevation();
    method public int getHeight();
    method public int getInputMethodMode();
    method public int getMaxAvailableHeight(android.view.View);
@@ -37306,6 +37308,7 @@ package android.widget {
    method public void setBackgroundDrawable(android.graphics.drawable.Drawable);
    method public void setClippingEnabled(boolean);
    method public void setContentView(android.view.View);
    method public void setElevation(float);
    method public void setFocusable(boolean);
    method public void setHeight(int);
    method public void setIgnoreCheekPress();
+14 −10
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package android.view;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Rect;
import android.util.DisplayMetrics;
import android.view.Surface.OutOfResourcesException;

@@ -247,21 +248,24 @@ public abstract class HardwareRenderer {
    abstract void detachSurfaceTexture(long hardwareLayer);

    /**
     * Setup the hardware renderer for drawing. This is called whenever the
     * size of the target surface changes or when the surface is first created.
     * Setup the hardware renderer for drawing. This is called whenever the size
     * of the target surface changes or when the surface is first created.
     *
     * @param width Width of the drawing surface.
     * @param height Height of the drawing surface.
     * @param surfaceInsets Insets between the drawing surface and actual
     *            surface bounds.
     * @param lightX X position of the shadow casting light
     * @param lightY Y position of the shadow casting light
     * @param lightZ Z position of the shadow casting light
     * @param lightRadius radius of the shadow casting light
     */
    abstract void setup(int width, int height, float lightX, float lightY, float lightZ, float lightRadius);
    abstract void setup(int width, int height, Rect surfaceInsets, float lightX, float lightY,
            float lightZ, float lightRadius);

    /**
     * Gets the current width of the surface. This is the width that the surface
     * was last set to in a call to {@link #setup(int, int, float, float, float, float)}.
     * was last set to in a call to {@link #setup(int, int, Rect, float, float, float, float)}.
     *
     * @return the current width of the surface
     */
@@ -269,7 +273,7 @@ public abstract class HardwareRenderer {

    /**
     * Gets the current height of the surface. This is the height that the surface
     * was last set to in a call to {@link #setup(int, int, float, float, float, float)}.
     * was last set to in a call to {@link #setup(int, int, Rect, float, float, float, float)}.
     *
     * @return the current width of the surface
     */
@@ -344,7 +348,6 @@ public abstract class HardwareRenderer {
     * @param view The view to draw.
     * @param attachInfo AttachInfo tied to the specified view.
     * @param callbacks Callbacks invoked when drawing happens.
     * @param dirty The dirty rectangle to update, can be null.
     */
    abstract void draw(View view, View.AttachInfo attachInfo, HardwareDrawCallbacks callbacks);

@@ -369,17 +372,18 @@ public abstract class HardwareRenderer {
     * @param height The height of the drawing surface.
     * @param surface The surface to hardware accelerate
     * @param metrics The display metrics used to draw the output.
     * @param surfaceInsets The drawing surface insets to apply
     *
     * @return true if the surface was initialized, false otherwise. Returning
     *         false might mean that the surface was already initialized.
     */
    boolean initializeIfNeeded(int width, int height, Surface surface, DisplayMetrics metrics)
    boolean initializeIfNeeded(int width, int height, Surface surface, Rect surfaceInsets, DisplayMetrics metrics)
            throws OutOfResourcesException {
        if (isRequested()) {
            // We lost the gl context, so recreate it.
            if (!isEnabled()) {
                if (initialize(surface)) {
                    setup(width, height, metrics);
                    setup(width, height, surfaceInsets, metrics);
                    return true;
                }
            }
@@ -387,12 +391,12 @@ public abstract class HardwareRenderer {
        return false;
    }

    void setup(int width, int height, DisplayMetrics metrics) {
    void setup(int width, int height, Rect surfaceInsets, DisplayMetrics metrics) {
        float lightX = width / 2.0f;
        float lightY = -400 * metrics.density;
        float lightZ = 800 * metrics.density;
        float lightRadius = 800 * metrics.density;
        setup(width, height, lightX, lightY, lightZ, lightRadius);
        setup(width, height, surfaceInsets, lightX, lightY, lightZ, lightRadius);
    }

    /**
+27 −4
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package android.view;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.os.IBinder;
import android.os.RemoteException;
@@ -67,7 +68,16 @@ public class ThreadedRenderer extends HardwareRenderer {
        PROFILE_PROPERTY_VISUALIZE_BARS,
    };

    // Size of the rendered content.
    private int mWidth, mHeight;

    // Actual size of the drawing surface.
    private int mSurfaceWidth, mSurfaceHeight;

    // Insets between the drawing surface and rendered content. These are
    // applied as translation when updating the root render node.
    private int mInsetTop, mInsetLeft;

    private long mNativeProxy;
    private boolean mInitialized = false;
    private RenderNode mRootNode;
@@ -154,11 +164,23 @@ public class ThreadedRenderer extends HardwareRenderer {
    }

    @Override
    void setup(int width, int height, float lightX, float lightY, float lightZ, float lightRadius) {
    void setup(int width, int height, Rect surfaceInsets, float lightX, float lightY, float lightZ,
            float lightRadius) {
        mWidth = width;
        mHeight = height;
        mRootNode.setLeftTopRightBottom(0, 0, mWidth, mHeight);
        nSetup(mNativeProxy, width, height, lightX, lightY, lightZ, lightRadius);
        if (surfaceInsets != null) {
            mInsetLeft = surfaceInsets.left;
            mInsetTop = surfaceInsets.top;
            mSurfaceWidth = width + mInsetLeft + surfaceInsets.right;
            mSurfaceHeight = height + mInsetTop + surfaceInsets.bottom;
        } else {
            mInsetLeft = 0;
            mInsetTop = 0;
            mSurfaceWidth = width;
            mSurfaceHeight = height;
        }
        mRootNode.setLeftTopRightBottom(-mInsetLeft, -mInsetTop, mSurfaceWidth, mSurfaceHeight);
        nSetup(mNativeProxy, mSurfaceWidth, mSurfaceHeight, lightX, lightY, lightZ, lightRadius);
    }

    @Override
@@ -214,9 +236,10 @@ public class ThreadedRenderer extends HardwareRenderer {
        view.mPrivateFlags &= ~View.PFLAG_INVALIDATED;

        Trace.traceBegin(Trace.TRACE_TAG_VIEW, "getDisplayList");
        HardwareCanvas canvas = mRootNode.start(mWidth, mHeight);
        HardwareCanvas canvas = mRootNode.start(mSurfaceWidth, mSurfaceHeight);
        try {
            canvas.save();
            canvas.translate(mInsetLeft, mInsetTop);
            callbacks.onHardwarePreDraw(canvas);
            canvas.drawRenderNode(view.getDisplayList());
            callbacks.onHardwarePostDraw(canvas);
+28 −17
Original line number Diff line number Diff line
@@ -1713,7 +1713,8 @@ public final class ViewRootImpl implements ViewParent,
                if (hwInitialized ||
                        mWidth != mAttachInfo.mHardwareRenderer.getWidth() ||
                        mHeight != mAttachInfo.mHardwareRenderer.getHeight()) {
                    mAttachInfo.mHardwareRenderer.setup(mWidth, mHeight,
                    final Rect shadowInsets = params != null ? params.shadowInsets : null;
                    mAttachInfo.mHardwareRenderer.setup(mWidth, mHeight, shadowInsets,
                            mAttachInfo.mRootView.getResources().getDisplayMetrics());
                    if (!hwInitialized) {
                        mAttachInfo.mHardwareRenderer.invalidate(mSurface);
@@ -2211,20 +2212,22 @@ public final class ViewRootImpl implements ViewParent,
        return measureSpec;
    }

    int mHardwareXOffset;
    int mHardwareYOffset;
    int mResizeAlpha;
    final Paint mResizePaint = new Paint();

    @Override
    public void onHardwarePreDraw(HardwareCanvas canvas) {
        canvas.translate(0, -mHardwareYOffset);
        canvas.translate(-mHardwareXOffset, -mHardwareYOffset);
    }

    @Override
    public void onHardwarePostDraw(HardwareCanvas canvas) {
        if (mResizeBuffer != null) {
            mResizePaint.setAlpha(mResizeAlpha);
            canvas.drawHardwareLayer(mResizeBuffer, 0.0f, mHardwareYOffset, mResizePaint);
            canvas.drawHardwareLayer(mResizeBuffer, mHardwareXOffset, mHardwareYOffset,
                    mResizePaint);
        }
        drawAccessibilityFocusedDrawableIfNeeded(canvas);
    }
@@ -2368,15 +2371,17 @@ public final class ViewRootImpl implements ViewParent,
            attachInfo.mTreeObserver.dispatchOnScrollChanged();
        }

        int yoff;
        final WindowManager.LayoutParams params = mWindowAttributes;
        final Rect surfaceInsets = params != null ? params.shadowInsets : null;
        boolean animating = mScroller != null && mScroller.computeScrollOffset();
        final int curScrollY;
        if (animating) {
            yoff = mScroller.getCurrY();
            curScrollY = mScroller.getCurrY();
        } else {
            yoff = mScrollY;
            curScrollY = mScrollY;
        }
        if (mCurScrollY != yoff) {
            mCurScrollY = yoff;
        if (mCurScrollY != curScrollY) {
            mCurScrollY = curScrollY;
            fullRedrawNeeded = true;
        }

@@ -2425,11 +2430,14 @@ public final class ViewRootImpl implements ViewParent,

        attachInfo.mTreeObserver.dispatchOnDraw();

        final int xOffset = surfaceInsets != null ? -surfaceInsets.left : 0;
        final int yOffset = curScrollY + (surfaceInsets != null ? -surfaceInsets.top : 0);
        if (!dirty.isEmpty() || mIsAnimating) {
            if (attachInfo.mHardwareRenderer != null && attachInfo.mHardwareRenderer.isEnabled()) {
                // Draw with hardware renderer.
                mIsAnimating = false;
                mHardwareYOffset = yoff;
                mHardwareYOffset = yOffset;
                mHardwareXOffset = xOffset;
                mResizeAlpha = resizeAlpha;

                dirty.setEmpty();
@@ -2450,8 +2458,9 @@ public final class ViewRootImpl implements ViewParent,
                        attachInfo.mHardwareRenderer.isRequested()) {

                    try {
                        attachInfo.mHardwareRenderer.initializeIfNeeded(mWidth, mHeight,
                                mSurface, attachInfo.mRootView.getResources().getDisplayMetrics());
                        attachInfo.mHardwareRenderer.initializeIfNeeded(
                                mWidth, mHeight, mSurface, surfaceInsets,
                                attachInfo.mRootView.getResources().getDisplayMetrics());
                    } catch (OutOfResourcesException e) {
                        handleOutOfResourcesException(e);
                        return;
@@ -2462,7 +2471,7 @@ public final class ViewRootImpl implements ViewParent,
                    return;
                }

                if (!drawSoftware(surface, attachInfo, yoff, scalingRequired, dirty)) {
                if (!drawSoftware(surface, attachInfo, xOffset, yOffset, scalingRequired, dirty)) {
                    return;
                }
            }
@@ -2475,9 +2484,9 @@ public final class ViewRootImpl implements ViewParent,
    }

    /**
     * @return true if drawing was succesfull, false if an error occurred
     * @return true if drawing was successful, false if an error occurred
     */
    private boolean drawSoftware(Surface surface, AttachInfo attachInfo, int yoff,
    private boolean drawSoftware(Surface surface, AttachInfo attachInfo, int xoff, int yoff,
            boolean scalingRequired, Rect dirty) {

        // Draw with software renderer.
@@ -2526,7 +2535,7 @@ public final class ViewRootImpl implements ViewParent,
            // If we are applying an offset, we need to clear the area
            // where the offset doesn't appear to avoid having garbage
            // left in the blank areas.
            if (!canvas.isOpaque() || yoff != 0) {
            if (!canvas.isOpaque() || yoff != 0 || xoff != 0) {
                canvas.drawColor(0, PorterDuff.Mode.CLEAR);
            }

@@ -2542,7 +2551,7 @@ public final class ViewRootImpl implements ViewParent,
                        ", compatibilityInfo=" + cxt.getResources().getCompatibilityInfo());
            }
            try {
                canvas.translate(0, -yoff);
                canvas.translate(-xoff, -yoff);
                if (mTranslator != null) {
                    mTranslator.translateCanvas(canvas);
                }
@@ -3147,8 +3156,10 @@ public final class ViewRootImpl implements ViewParent,
                        if (mAttachInfo.mHardwareRenderer != null && mSurface.isValid()){
                            mFullRedrawNeeded = true;
                            try {
                                final WindowManager.LayoutParams lp = mWindowAttributes;
                                final Rect surfaceInsets = lp != null ? lp.shadowInsets : null;
                                mAttachInfo.mHardwareRenderer.initializeIfNeeded(
                                        mWidth, mHeight, mSurface,
                                        mWidth, mHeight, mSurface, surfaceInsets,
                                        mAttachInfo.mRootView.getResources().getDisplayMetrics());
                            } catch (OutOfResourcesException e) {
                                Log.e(TAG, "OutOfResourcesException locking surface", e);
+24 −0
Original line number Diff line number Diff line
@@ -19,7 +19,9 @@ package android.view;
import android.app.Presentation;
import android.content.Context;
import android.content.pm.ActivityInfo;
import android.graphics.Insets;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.os.IBinder;
import android.os.Parcel;
import android.os.Parcelable;
@@ -1291,6 +1293,13 @@ public interface WindowManager extends ViewManager {
         */
        public float verticalMargin;

        /**
         * Positive insets between the drawing surface and window content.
         *
         * @hide
         */
        public Rect shadowInsets = new Rect();
    
        /**
         * The desired bitmap format.  May be one of the constants in
         * {@link android.graphics.PixelFormat}.  Default is OPAQUE.
@@ -1571,6 +1580,10 @@ public interface WindowManager extends ViewManager {
            out.writeInt(hasSystemUiListeners ? 1 : 0);
            out.writeInt(inputFeatures);
            out.writeLong(userActivityTimeout);
            out.writeInt(shadowInsets.left);
            out.writeInt(shadowInsets.top);
            out.writeInt(shadowInsets.right);
            out.writeInt(shadowInsets.bottom);
        }
        
        public static final Parcelable.Creator<LayoutParams> CREATOR
@@ -1613,6 +1626,7 @@ public interface WindowManager extends ViewManager {
            hasSystemUiListeners = in.readInt() != 0;
            inputFeatures = in.readInt();
            userActivityTimeout = in.readLong();
            shadowInsets.set(in.readInt(), in.readInt(), in.readInt(), in.readInt());
        }
    
        @SuppressWarnings({"PointlessBitwiseExpression"})
@@ -1644,6 +1658,8 @@ public interface WindowManager extends ViewManager {
        /** {@hide} */
        public static final int TRANSLUCENT_FLAGS_CHANGED = 1<<19;
        /** {@hide} */
        public static final int SHADOW_INSETS_CHANGED = 1<<20;
        /** {@hide} */
        public static final int EVERYTHING_CHANGED = 0xffffffff;

        // internal buffer to backup/restore parameters under compatibility mode.
@@ -1778,6 +1794,11 @@ public interface WindowManager extends ViewManager {
                changes |= USER_ACTIVITY_TIMEOUT_CHANGED;
            }

            if (!shadowInsets.equals(o.shadowInsets)) {
                shadowInsets.set(o.shadowInsets);
                changes |= SHADOW_INSETS_CHANGED;
            }

            return changes;
        }
    
@@ -1877,6 +1898,9 @@ public interface WindowManager extends ViewManager {
            if (userActivityTimeout >= 0) {
                sb.append(" userActivityTimeout=").append(userActivityTimeout);
            }
            if (!shadowInsets.equals(Insets.NONE)) {
                sb.append(" shadowInsets=").append(shadowInsets);
            }
            sb.append('}');
            return sb.toString();
        }
Loading