Home | History | Annotate | Download | only in recent
      1 /*
      2  * Copyright (C) 2011 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.systemui.recent;
     18 
     19 import android.animation.LayoutTransition;
     20 import android.content.Context;
     21 import android.content.res.TypedArray;
     22 import android.graphics.Canvas;
     23 import android.graphics.LinearGradient;
     24 import android.graphics.Matrix;
     25 import android.graphics.Paint;
     26 import android.graphics.Shader;
     27 import android.graphics.drawable.Drawable;
     28 import android.util.AttributeSet;
     29 import android.view.View;
     30 import android.view.ViewConfiguration;
     31 import android.view.ViewGroup;
     32 import android.widget.LinearLayout;
     33 
     34 import com.android.systemui.R;
     35 
     36 public class RecentsScrollViewPerformanceHelper {
     37     public static final boolean OPTIMIZE_SW_RENDERED_RECENTS = true;
     38     public static final boolean USE_DARK_FADE_IN_HW_ACCELERATED_MODE = true;
     39     private View mScrollView;
     40     private RecentsCallback mCallback;
     41 
     42     private int mFadingEdgeLength;
     43     private Context mContext;
     44     private boolean mIsVertical;
     45     private boolean mSoftwareRendered = false;
     46     private boolean mAttachedToWindow = false;
     47 
     48     public static RecentsScrollViewPerformanceHelper create(Context context,
     49             AttributeSet attrs, View scrollView, boolean isVertical) {
     50         boolean isTablet = context.getResources().
     51                 getBoolean(R.bool.config_recents_interface_for_tablets);
     52         if (!isTablet && (OPTIMIZE_SW_RENDERED_RECENTS || USE_DARK_FADE_IN_HW_ACCELERATED_MODE)) {
     53             return new RecentsScrollViewPerformanceHelper(context, attrs, scrollView, isVertical);
     54         } else {
     55             return null;
     56         }
     57     }
     58 
     59     public RecentsScrollViewPerformanceHelper(Context context,
     60             AttributeSet attrs, View scrollView, boolean isVertical) {
     61         mScrollView = scrollView;
     62         mContext = context;
     63         TypedArray a = context.obtainStyledAttributes(attrs, com.android.internal.R.styleable.View);
     64         mFadingEdgeLength = a.getDimensionPixelSize(android.R.styleable.View_fadingEdgeLength,
     65                 ViewConfiguration.get(context).getScaledFadingEdgeLength());
     66         mIsVertical = isVertical;
     67     }
     68 
     69     public void onAttachedToWindowCallback(
     70             RecentsCallback callback, LinearLayout layout, boolean hardwareAccelerated) {
     71         mSoftwareRendered = !hardwareAccelerated;
     72         if ((mSoftwareRendered && OPTIMIZE_SW_RENDERED_RECENTS)
     73                 || USE_DARK_FADE_IN_HW_ACCELERATED_MODE) {
     74             mScrollView.setVerticalFadingEdgeEnabled(false);
     75             mScrollView.setHorizontalFadingEdgeEnabled(false);
     76         }
     77     }
     78 
     79     public void addViewCallback(View newLinearLayoutChild) {
     80         if (mSoftwareRendered && OPTIMIZE_SW_RENDERED_RECENTS) {
     81             final RecentsPanelView.ViewHolder holder =
     82                     (RecentsPanelView.ViewHolder) newLinearLayoutChild.getTag();
     83             holder.labelView.setDrawingCacheEnabled(true);
     84             holder.labelView.buildDrawingCache();
     85         }
     86     }
     87 
     88     public void drawCallback(Canvas canvas,
     89             int left, int right, int top, int bottom, int scrollX, int scrollY,
     90             float topFadingEdgeStrength, float bottomFadingEdgeStrength,
     91             float leftFadingEdgeStrength, float rightFadingEdgeStrength) {
     92 
     93         if ((mSoftwareRendered && OPTIMIZE_SW_RENDERED_RECENTS)
     94                 || USE_DARK_FADE_IN_HW_ACCELERATED_MODE) {
     95             Paint p = new Paint();
     96             Matrix matrix = new Matrix();
     97             // use use a height of 1, and then wack the matrix each time we
     98             // actually use it.
     99             Shader fade = new LinearGradient(0, 0, 0, 1, 0xCC000000, 0, Shader.TileMode.CLAMP);
    100             // PULL OUT THIS CONSTANT
    101 
    102             p.setShader(fade);
    103 
    104             // draw the fade effect
    105             boolean drawTop = false;
    106             boolean drawBottom = false;
    107             boolean drawLeft = false;
    108             boolean drawRight = false;
    109 
    110             float topFadeStrength = 0.0f;
    111             float bottomFadeStrength = 0.0f;
    112             float leftFadeStrength = 0.0f;
    113             float rightFadeStrength = 0.0f;
    114 
    115             final float fadeHeight = mFadingEdgeLength;
    116             int length = (int) fadeHeight;
    117 
    118             // clip the fade length if top and bottom fades overlap
    119             // overlapping fades produce odd-looking artifacts
    120             if (mIsVertical && (top + length > bottom - length)) {
    121                 length = (bottom - top) / 2;
    122             }
    123 
    124             // also clip horizontal fades if necessary
    125             if (!mIsVertical && (left + length > right - length)) {
    126                 length = (right - left) / 2;
    127             }
    128 
    129             if (mIsVertical) {
    130                 topFadeStrength = Math.max(0.0f, Math.min(1.0f, topFadingEdgeStrength));
    131                 drawTop = topFadeStrength * fadeHeight > 1.0f;
    132                 bottomFadeStrength = Math.max(0.0f, Math.min(1.0f, bottomFadingEdgeStrength));
    133                 drawBottom = bottomFadeStrength * fadeHeight > 1.0f;
    134             }
    135 
    136             if (!mIsVertical) {
    137                 leftFadeStrength = Math.max(0.0f, Math.min(1.0f, leftFadingEdgeStrength));
    138                 drawLeft = leftFadeStrength * fadeHeight > 1.0f;
    139                 rightFadeStrength = Math.max(0.0f, Math.min(1.0f, rightFadingEdgeStrength));
    140                 drawRight = rightFadeStrength * fadeHeight > 1.0f;
    141             }
    142 
    143             if (drawTop) {
    144                 matrix.setScale(1, fadeHeight * topFadeStrength);
    145                 matrix.postTranslate(left, top);
    146                 fade.setLocalMatrix(matrix);
    147                 canvas.drawRect(left, top, right, top + length, p);
    148             }
    149 
    150             if (drawBottom) {
    151                 matrix.setScale(1, fadeHeight * bottomFadeStrength);
    152                 matrix.postRotate(180);
    153                 matrix.postTranslate(left, bottom);
    154                 fade.setLocalMatrix(matrix);
    155                 canvas.drawRect(left, bottom - length, right, bottom, p);
    156             }
    157 
    158             if (drawLeft) {
    159                 matrix.setScale(1, fadeHeight * leftFadeStrength);
    160                 matrix.postRotate(-90);
    161                 matrix.postTranslate(left, top);
    162                 fade.setLocalMatrix(matrix);
    163                 canvas.drawRect(left, top, left + length, bottom, p);
    164             }
    165 
    166             if (drawRight) {
    167                 matrix.setScale(1, fadeHeight * rightFadeStrength);
    168                 matrix.postRotate(90);
    169                 matrix.postTranslate(right, top);
    170                 fade.setLocalMatrix(matrix);
    171                 canvas.drawRect(right - length, top, right, bottom, p);
    172             }
    173         }
    174     }
    175 
    176     public int getVerticalFadingEdgeLengthCallback() {
    177         return mFadingEdgeLength;
    178     }
    179 
    180     public int getHorizontalFadingEdgeLengthCallback() {
    181         return mFadingEdgeLength;
    182     }
    183 
    184 }
    185