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

Commit 7c02d7ad authored by Daniel Chapin's avatar Daniel Chapin Committed by Android (Google) Code Review
Browse files

Merge "Fixes for ImageView drawable visibility dispatch" into nyc-dr1-dev

parents 19628b25 06f9eb8b
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -10384,7 +10384,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
     *                  ancestors or by window visibility
     * @return true if this view is visible to the user, not counting clipping or overlapping
     */
    @Visibility boolean dispatchVisibilityAggregated(boolean isVisible) {
    boolean dispatchVisibilityAggregated(boolean isVisible) {
        final boolean thisVisible = getVisibility() == VISIBLE;
        // If we're not visible but something is telling us we are, ignore it.
        if (thisVisible || !isVisible) {
@@ -15527,7 +15527,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
        if (vis != GONE) {
            onWindowVisibilityChanged(vis);
            if (isShown()) {
                // Calling onVisibilityChanged directly here since the subtree will also
                // Calling onVisibilityAggregated directly here since the subtree will also
                // receive dispatchAttachedToWindow and this same call
                onVisibilityAggregated(vis == VISIBLE);
            }
+3 −8
Original line number Diff line number Diff line
@@ -52,7 +52,6 @@ import android.hardware.input.InputManager;
import android.media.AudioManager;
import android.os.Binder;
import android.os.Build;
import android.os.Build.VERSION_CODES;
import android.os.Bundle;
import android.os.Debug;
import android.os.Handler;
@@ -1468,6 +1467,8 @@ public final class ViewRootImpl implements ViewParent,
        final int viewVisibility = getHostVisibility();
        final boolean viewVisibilityChanged = !mFirst
                && (mViewVisibility != viewVisibility || mNewSurfaceNeeded);
        final boolean viewUserVisibilityChanged = !mFirst &&
                ((mViewVisibility == View.VISIBLE) != (viewVisibility == View.VISIBLE));

        WindowManager.LayoutParams params = null;
        if (mWindowAttributesChanged) {
@@ -1541,13 +1542,7 @@ public final class ViewRootImpl implements ViewParent,
        if (viewVisibilityChanged) {
            mAttachInfo.mWindowVisibility = viewVisibility;
            host.dispatchWindowVisibilityChanged(viewVisibility);

            // Prior to N we didn't have dispatchVisibilityAggregated to give a more accurate
            // view into when views are visible to the user or not. ImageView never dealt with
            // telling its drawable about window visibility, among other things. Some apps cause
            // an additional crossfade animation when windows become visible if they get this
            // additional call, so only send it to new apps to avoid new visual jank.
            if (host.getContext().getApplicationInfo().targetSdkVersion >= VERSION_CODES.N) {
            if (viewUserVisibilityChanged) {
                host.dispatchVisibilityAggregated(viewVisibility == View.VISIBLE);
            }
            if (viewVisibility != View.VISIBLE || mNewSurfaceNeeded) {
+60 −15
Original line number Diff line number Diff line
@@ -22,7 +22,6 @@ import android.annotation.Nullable;
import android.content.ContentResolver;
import android.content.Context;
import android.content.res.ColorStateList;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Canvas;
@@ -115,11 +114,17 @@ public class ImageView extends View {
    private int mBaseline = -1;
    private boolean mBaselineAlignBottom = false;

    // AdjustViewBounds behavior will be in compatibility mode for older apps.
    private boolean mAdjustViewBoundsCompat = false;
    /** Compatibility modes dependent on targetSdkVersion of the app. */
    private static boolean sCompatDone;

    /** AdjustViewBounds behavior will be in compatibility mode for older apps. */
    private static boolean sCompatAdjustViewBounds;

    /** Whether to pass Resources when creating the source from a stream. */
    private boolean mUseCorrectStreamDensity;
    private static boolean sCompatUseCorrectStreamDensity;

    /** Whether to use pre-Nougat drawable visibility dispatching conditions. */
    private static boolean sCompatDrawableVisibilityDispatch;

    private static final ScaleType[] sScaleTypeArray = {
        ScaleType.MATRIX,
@@ -206,9 +211,13 @@ public class ImageView extends View {
        mMatrix = new Matrix();
        mScaleType = ScaleType.FIT_CENTER;

        if (!sCompatDone) {
            final int targetSdkVersion = mContext.getApplicationInfo().targetSdkVersion;
        mAdjustViewBoundsCompat = targetSdkVersion <= Build.VERSION_CODES.JELLY_BEAN_MR1;
        mUseCorrectStreamDensity = targetSdkVersion > Build.VERSION_CODES.M;
            sCompatAdjustViewBounds = targetSdkVersion <= Build.VERSION_CODES.JELLY_BEAN_MR1;
            sCompatUseCorrectStreamDensity = targetSdkVersion > Build.VERSION_CODES.M;
            sCompatDrawableVisibilityDispatch = targetSdkVersion < Build.VERSION_CODES.N;
            sCompatDone = true;
        }
    }

    @Override
@@ -881,8 +890,8 @@ public class ImageView extends View {
            InputStream stream = null;
            try {
                stream = mContext.getContentResolver().openInputStream(uri);
                return Drawable.createFromResourceStream(
                        mUseCorrectStreamDensity ? getResources() : null, null, stream, null);
                return Drawable.createFromResourceStream(sCompatUseCorrectStreamDensity
                        ? getResources() : null, null, stream, null);
            } catch (Exception e) {
                Log.w(LOG_TAG, "Unable to open content: " + uri, e);
            } finally {
@@ -917,10 +926,13 @@ public class ImageView extends View {
            mRecycleableBitmapDrawable.setBitmap(null);
        }

        boolean sameDrawable = false;

        if (mDrawable != null) {
            sameDrawable = mDrawable == d;
            mDrawable.setCallback(null);
            unscheduleDrawable(mDrawable);
            if (isAttachedToWindow()) {
            if (!sCompatDrawableVisibilityDispatch && !sameDrawable && isAttachedToWindow()) {
                mDrawable.setVisible(false, false);
            }
        }
@@ -933,8 +945,12 @@ public class ImageView extends View {
            if (d.isStateful()) {
                d.setState(getDrawableState());
            }
            d.setVisible(isAttachedToWindow() && getWindowVisibility() == VISIBLE && isShown(),
                    true);
            if (!sameDrawable || sCompatDrawableVisibilityDispatch) {
                final boolean visible = sCompatDrawableVisibilityDispatch
                        ? getVisibility() == VISIBLE
                        : isAttachedToWindow() && getWindowVisibility() == VISIBLE && isShown();
                d.setVisible(visible, true);
            }
            d.setLevel(mLevel);
            mDrawableWidth = d.getIntrinsicWidth();
            mDrawableHeight = d.getIntrinsicHeight();
@@ -1057,7 +1073,7 @@ public class ImageView extends View {
                                pleft + pright;

                        // Allow the width to outgrow its original estimate if height is fixed.
                        if (!resizeHeight && !mAdjustViewBoundsCompat) {
                        if (!resizeHeight && !sCompatAdjustViewBounds) {
                            widthSize = resolveAdjustedSize(newWidth, mMaxWidth, widthMeasureSpec);
                        }

@@ -1073,7 +1089,7 @@ public class ImageView extends View {
                                ptop + pbottom;

                        // Allow the height to outgrow its original estimate if width is fixed.
                        if (!resizeWidth && !mAdjustViewBoundsCompat) {
                        if (!resizeWidth && !sCompatAdjustViewBounds) {
                            heightSize = resolveAdjustedSize(newHeight, mMaxHeight,
                                    heightMeasureSpec);
                        }
@@ -1512,11 +1528,40 @@ public class ImageView extends View {
    @Override
    public void onVisibilityAggregated(boolean isVisible) {
        super.onVisibilityAggregated(isVisible);
        if (mDrawable != null) {
        // Only do this for new apps post-Nougat
        if (mDrawable != null && !sCompatDrawableVisibilityDispatch) {
            mDrawable.setVisible(isVisible, false);
        }
    }

    @RemotableViewMethod
    @Override
    public void setVisibility(int visibility) {
        super.setVisibility(visibility);
        // Only do this for old apps pre-Nougat; new apps use onVisibilityAggregated
        if (mDrawable != null && sCompatDrawableVisibilityDispatch) {
            mDrawable.setVisible(visibility == VISIBLE, false);
        }
    }

    @Override
    protected void onAttachedToWindow() {
        super.onAttachedToWindow();
        // Only do this for old apps pre-Nougat; new apps use onVisibilityAggregated
        if (mDrawable != null && sCompatDrawableVisibilityDispatch) {
            mDrawable.setVisible(getVisibility() == VISIBLE, false);
        }
    }

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        // Only do this for old apps pre-Nougat; new apps use onVisibilityAggregated
        if (mDrawable != null && sCompatDrawableVisibilityDispatch) {
            mDrawable.setVisible(false, false);
        }
    }

    @Override
    public CharSequence getAccessibilityClassName() {
        return ImageView.class.getName();