13cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka/*
23cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka * Copyright (C) 2011 The Android Open Source Project
33cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka *
43cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka * Licensed under the Apache License, Version 2.0 (the "License");
53cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka * you may not use this file except in compliance with the License.
63cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka * You may obtain a copy of the License at
73cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka *
83cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka *      http://www.apache.org/licenses/LICENSE-2.0
93cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka *
103cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka * Unless required by applicable law or agreed to in writing, software
113cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka * distributed under the License is distributed on an "AS IS" BASIS,
123cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
133cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka * See the License for the specific language governing permissions and
143cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka * limitations under the License.
153cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka */
163cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka
173cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurkapackage com.android.systemui.recent;
183cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka
193cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurkaimport android.animation.LayoutTransition;
203cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurkaimport android.content.Context;
213cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurkaimport android.content.res.TypedArray;
223cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurkaimport android.graphics.Canvas;
233cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurkaimport android.graphics.LinearGradient;
243cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurkaimport android.graphics.Matrix;
253cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurkaimport android.graphics.Paint;
263cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurkaimport android.graphics.Shader;
273cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurkaimport android.graphics.drawable.Drawable;
283cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurkaimport android.util.AttributeSet;
293cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurkaimport android.view.View;
303cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurkaimport android.view.ViewConfiguration;
313cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurkaimport android.view.ViewGroup;
323cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurkaimport android.widget.LinearLayout;
333cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka
343cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurkaimport com.android.systemui.R;
353cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka
363cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurkapublic class RecentsScrollViewPerformanceHelper {
373cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka    public static final boolean OPTIMIZE_SW_RENDERED_RECENTS = true;
383cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka    public static final boolean USE_DARK_FADE_IN_HW_ACCELERATED_MODE = true;
393cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka    private View mScrollView;
403cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka    private LinearLayout mLinearLayout;
413cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka    private RecentsCallback mCallback;
423cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka
433cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka    private boolean mShowBackground = false;
443cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka    private int mFadingEdgeLength;
453cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka    private Drawable.ConstantState mBackgroundDrawable;
463cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka    private Context mContext;
473cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka    private boolean mIsVertical;
483cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka    private boolean mFirstTime = true;
493cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka    private boolean mSoftwareRendered = false;
503cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka    private boolean mAttachedToWindow = false;
513cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka
523cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka    public static RecentsScrollViewPerformanceHelper create(Context context,
533cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka            AttributeSet attrs, View scrollView, boolean isVertical) {
543cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka        boolean isTablet = context.getResources().
553cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka                getBoolean(R.bool.config_recents_interface_for_tablets);
563cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka        if (!isTablet && (OPTIMIZE_SW_RENDERED_RECENTS || USE_DARK_FADE_IN_HW_ACCELERATED_MODE)) {
573cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka            return new RecentsScrollViewPerformanceHelper(context, attrs, scrollView, isVertical);
583cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka        } else {
593cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka            return null;
603cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka        }
613cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka    }
623cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka
633cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka    public RecentsScrollViewPerformanceHelper(Context context,
643cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka            AttributeSet attrs, View scrollView, boolean isVertical) {
653cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka        mScrollView = scrollView;
663cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka        mContext = context;
673cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka        TypedArray a = context.obtainStyledAttributes(attrs, com.android.internal.R.styleable.View);
683cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka        mFadingEdgeLength = a.getDimensionPixelSize(android.R.styleable.View_fadingEdgeLength,
693cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka                ViewConfiguration.get(context).getScaledFadingEdgeLength());
703cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka        mIsVertical = isVertical;
713cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka    }
723cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka
733cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka    public void onAttachedToWindowCallback(
743cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka            RecentsCallback callback, LinearLayout layout, boolean hardwareAccelerated) {
753cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka        mSoftwareRendered = !hardwareAccelerated;
763cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka        if ((mSoftwareRendered && OPTIMIZE_SW_RENDERED_RECENTS)
773cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka                || USE_DARK_FADE_IN_HW_ACCELERATED_MODE) {
783cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka            mScrollView.setVerticalFadingEdgeEnabled(false);
793cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka            mScrollView.setHorizontalFadingEdgeEnabled(false);
803cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka        }
813cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka        if (mSoftwareRendered && OPTIMIZE_SW_RENDERED_RECENTS) {
823cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka            mCallback = callback;
833cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka            mLinearLayout = layout;
843cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka            mAttachedToWindow = true;
853cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka            mBackgroundDrawable = mContext.getResources()
8692c88eb91dbfe6e96342c8e1dbfe3a59d9a3ffdeMichael Jurka                .getDrawable(R.drawable.status_bar_recents_background_solid).getConstantState();
873cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka            updateShowBackground();
883cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka        }
893cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka
903cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka    }
913cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka
923cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka    public void addViewCallback(View newLinearLayoutChild) {
933cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka        if (mSoftwareRendered && OPTIMIZE_SW_RENDERED_RECENTS) {
943cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka            final View view = newLinearLayoutChild;
953cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka            if (mShowBackground) {
963cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka                view.setBackgroundDrawable(mBackgroundDrawable.newDrawable());
973cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka                view.setDrawingCacheEnabled(true);
983cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka                view.buildDrawingCache();
993cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka            } else {
1003cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka                view.setBackgroundDrawable(null);
1013cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka                view.setDrawingCacheEnabled(false);
1023cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka                view.destroyDrawingCache();
1033cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka            }
1043cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka        }
1053cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka    }
1063cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka
1073cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka    public void onLayoutCallback() {
1083cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka        if (mSoftwareRendered && OPTIMIZE_SW_RENDERED_RECENTS) {
1093cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka            mScrollView.post(new Runnable() {
1103cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka                public void run() {
1113cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka                    updateShowBackground();
1123cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka                }
1133cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka            });
1143cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka        }
1153cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka    }
1163cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka
1173cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka    public void drawCallback(Canvas canvas,
1183cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka            int left, int right, int top, int bottom, int scrollX, int scrollY,
1193cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka            float topFadingEdgeStrength, float bottomFadingEdgeStrength,
1203cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka            float leftFadingEdgeStrength, float rightFadingEdgeStrength) {
1213cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka        if (mSoftwareRendered && OPTIMIZE_SW_RENDERED_RECENTS) {
1223cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka            if (mIsVertical) {
1233cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka                if (scrollY < 0) {
1243cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka                    Drawable d = mBackgroundDrawable.newDrawable().getCurrent();
1253cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka                    d.setBounds(0, scrollY, mScrollView.getWidth(), 0);
1263cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka                    d.draw(canvas);
1273cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka                } else {
1283cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka                    final int childHeight = mLinearLayout.getHeight();
1293cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka                    if (scrollY + mScrollView.getHeight() > childHeight) {
1303cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka                        Drawable d = mBackgroundDrawable.newDrawable().getCurrent();
1313cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka                        d.setBounds(0, childHeight, mScrollView.getWidth(),
1323cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka                                scrollY + mScrollView.getHeight());
1333cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka                        d.draw(canvas);
1343cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka                    }
1353cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka                }
1363cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka            } else {
1373cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka                if (scrollX < 0) {
1383cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka                    Drawable d = mBackgroundDrawable.newDrawable().getCurrent();
1393cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka                    d.setBounds(scrollX, 0, 0, mScrollView.getHeight());
1403cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka                    d.draw(canvas);
1413cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka                } else {
1423cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka                    final int childWidth = mLinearLayout.getWidth();
1433cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka                    if (scrollX + mScrollView.getWidth() > childWidth) {
1443cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka                        Drawable d = mBackgroundDrawable.newDrawable().getCurrent();
1453cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka                        d.setBounds(childWidth, 0,
1463cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka                                scrollX + mScrollView.getWidth(), mScrollView.getHeight());
1473cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka                        d.draw(canvas);
1483cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka                    }
1493cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka                }
1503cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka            }
1513cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka        }
1523cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka
1533cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka        if ((mSoftwareRendered && OPTIMIZE_SW_RENDERED_RECENTS)
1543cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka                || USE_DARK_FADE_IN_HW_ACCELERATED_MODE) {
1553cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka            Paint p = new Paint();
1563cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka            Matrix matrix = new Matrix();
1573cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka            // use use a height of 1, and then wack the matrix each time we
1583cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka            // actually use it.
1593cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka            Shader fade = new LinearGradient(0, 0, 0, 1, 0xCC000000, 0, Shader.TileMode.CLAMP);
1603cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka            // PULL OUT THIS CONSTANT
1613cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka
1623cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka            p.setShader(fade);
1633cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka
1643cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka            // draw the fade effect
1653cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka            boolean drawTop = false;
1663cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka            boolean drawBottom = false;
1673cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka            boolean drawLeft = false;
1683cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka            boolean drawRight = false;
1693cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka
1703cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka            float topFadeStrength = 0.0f;
1713cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka            float bottomFadeStrength = 0.0f;
1723cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka            float leftFadeStrength = 0.0f;
1733cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka            float rightFadeStrength = 0.0f;
1743cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka
1753cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka            final float fadeHeight = mFadingEdgeLength;
1763cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka            int length = (int) fadeHeight;
1773cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka
1783cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka            // clip the fade length if top and bottom fades overlap
1793cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka            // overlapping fades produce odd-looking artifacts
1803cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka            if (mIsVertical && (top + length > bottom - length)) {
1813cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka                length = (bottom - top) / 2;
1823cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka            }
1833cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka
1843cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka            // also clip horizontal fades if necessary
1853cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka            if (!mIsVertical && (left + length > right - length)) {
1863cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka                length = (right - left) / 2;
1873cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka            }
1883cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka
1893cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka            if (mIsVertical) {
1903cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka                topFadeStrength = Math.max(0.0f, Math.min(1.0f, topFadingEdgeStrength));
1913cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka                drawTop = topFadeStrength * fadeHeight > 1.0f;
1923cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka                bottomFadeStrength = Math.max(0.0f, Math.min(1.0f, bottomFadingEdgeStrength));
1933cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka                drawBottom = bottomFadeStrength * fadeHeight > 1.0f;
1943cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka            }
1953cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka
1963cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka            if (!mIsVertical) {
1973cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka                leftFadeStrength = Math.max(0.0f, Math.min(1.0f, leftFadingEdgeStrength));
1983cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka                drawLeft = leftFadeStrength * fadeHeight > 1.0f;
1993cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka                rightFadeStrength = Math.max(0.0f, Math.min(1.0f, rightFadingEdgeStrength));
2003cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka                drawRight = rightFadeStrength * fadeHeight > 1.0f;
2013cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka            }
2023cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka
2033cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka            if (drawTop) {
2043cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka                matrix.setScale(1, fadeHeight * topFadeStrength);
2053cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka                matrix.postTranslate(left, top);
2063cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka                fade.setLocalMatrix(matrix);
2073cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka                canvas.drawRect(left, top, right, top + length, p);
2083cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka            }
2093cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka
2103cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka            if (drawBottom) {
2113cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka                matrix.setScale(1, fadeHeight * bottomFadeStrength);
2123cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka                matrix.postRotate(180);
2133cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka                matrix.postTranslate(left, bottom);
2143cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka                fade.setLocalMatrix(matrix);
2153cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka                canvas.drawRect(left, bottom - length, right, bottom, p);
2163cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka            }
2173cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka
2183cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka            if (drawLeft) {
2193cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka                matrix.setScale(1, fadeHeight * leftFadeStrength);
2203cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka                matrix.postRotate(-90);
2213cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka                matrix.postTranslate(left, top);
2223cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka                fade.setLocalMatrix(matrix);
2233cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka                canvas.drawRect(left, top, left + length, bottom, p);
2243cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka            }
2253cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka
2263cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka            if (drawRight) {
2273cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka                matrix.setScale(1, fadeHeight * rightFadeStrength);
2283cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka                matrix.postRotate(90);
2293cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka                matrix.postTranslate(right, top);
2303cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka                fade.setLocalMatrix(matrix);
2313cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka                canvas.drawRect(right - length, top, right, bottom, p);
2323cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka            }
2333cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka        }
2343cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka    }
2353cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka
2363cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka    public int getVerticalFadingEdgeLengthCallback() {
2373cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka        return mFadingEdgeLength;
2383cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka    }
2393cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka
2403cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka    public int getHorizontalFadingEdgeLengthCallback() {
2413cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka        return mFadingEdgeLength;
2423cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka    }
2433cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka
2443cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka    public void setLayoutTransitionCallback(LayoutTransition transition) {
2453cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka        if (mSoftwareRendered && OPTIMIZE_SW_RENDERED_RECENTS) {
2463cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka            if (transition != null) {
2473cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka                transition.addTransitionListener(new LayoutTransition.TransitionListener() {
2483cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka                    @Override
2493cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka                    public void startTransition(LayoutTransition transition,
2503cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka                            ViewGroup container, View view, int transitionType) {
2513cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka                        updateShowBackground();
2523cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka                    }
2533cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka
2543cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka                    @Override
2553cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka                    public void endTransition(LayoutTransition transition,
2563cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka                            ViewGroup container, View view, int transitionType) {
2573cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka                        updateShowBackground();
2583cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka                    }
2593cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka                });
2603cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka            }
2613cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka        }
2623cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka    }
2633cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka
2643cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka    // Turn on/off drawing the background in our ancestor, and turn on/off drawing
2653cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka    // in the items in LinearLayout contained by this scrollview.
2663cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka    // Moving the background drawing to our children, and turning on a drawing cache
2673cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka    // for each of them, gives us a ~20fps gain when Recents is rendered in software
2683cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka    public void updateShowBackground() {
2693cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka        if (!mAttachedToWindow) {
2703cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka            // We haven't been initialized yet-- we'll get called again when we are
2713cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka            return;
2723cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka        }
2733cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka        if (mSoftwareRendered && OPTIMIZE_SW_RENDERED_RECENTS) {
2743cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka            LayoutTransition transition = mLinearLayout.getLayoutTransition();
2753cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka            int linearLayoutSize =
2763cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka                mIsVertical ? mLinearLayout.getHeight() : mLinearLayout.getWidth();
2773cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka            int scrollViewSize =
2783cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka                mIsVertical ? mScrollView.getHeight() : mScrollView.getWidth();
2793cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka            boolean show = !mScrollView.isHardwareAccelerated() &&
2803cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka                (linearLayoutSize > scrollViewSize) &&
2813cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka                !(transition != null && transition.isRunning()) &&
2823cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka                mCallback.isRecentsVisible();
2833cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka
2843cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka            if (!mFirstTime && show == mShowBackground) return;
2853cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka            mShowBackground = show;
2863cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka            mFirstTime = false;
2873cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka
2883cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka            mCallback.handleShowBackground(!show);
2893cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka            for (int i = 0; i < mLinearLayout.getChildCount(); i++) {
2903cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka                View v = mLinearLayout.getChildAt(i);
2913cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka                if (show) {
2923cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka                    v.setBackgroundDrawable(mBackgroundDrawable.newDrawable());
2933cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka                    v.setDrawingCacheEnabled(true);
2943cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka                    v.buildDrawingCache();
2953cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka                } else {
2963cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka                    v.setDrawingCacheEnabled(false);
2973cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka                    v.destroyDrawingCache();
2983cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka                    v.setBackgroundDrawable(null);
2993cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka                }
3003cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka            }
3013cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka        }
3023cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka    }
3033cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka
3043cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka}
305