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.content.Context;
     20 import android.content.res.TypedArray;
     21 import android.graphics.Canvas;
     22 import android.graphics.LinearGradient;
     23 import android.graphics.Matrix;
     24 import android.graphics.Paint;
     25 import android.graphics.Shader;
     26 import android.util.AttributeSet;
     27 import android.view.View;
     28 import android.view.ViewConfiguration;
     29 import android.widget.LinearLayout;
     30 
     31 import com.android.systemui.R;
     32 
     33 public class RecentsScrollViewPerformanceHelper {
     34     public static final boolean OPTIMIZE_SW_RENDERED_RECENTS = true;
     35     public static final boolean USE_DARK_FADE_IN_HW_ACCELERATED_MODE = true;
     36     private View mScrollView;
     37 
     38     private int mFadingEdgeLength;
     39     private boolean mIsVertical;
     40     private boolean mSoftwareRendered = false;
     41 
     42     public static RecentsScrollViewPerformanceHelper create(Context context,
     43             AttributeSet attrs, View scrollView, boolean isVertical) {
     44         boolean isTablet = context.getResources().
     45                 getBoolean(R.bool.config_recents_interface_for_tablets);
     46         if (!isTablet && (OPTIMIZE_SW_RENDERED_RECENTS || USE_DARK_FADE_IN_HW_ACCELERATED_MODE)) {
     47             return new RecentsScrollViewPerformanceHelper(context, attrs, scrollView, isVertical);
     48         } else {
     49             return null;
     50         }
     51     }
     52 
     53     public RecentsScrollViewPerformanceHelper(Context context,
     54             AttributeSet attrs, View scrollView, boolean isVertical) {
     55         mScrollView = scrollView;
     56         TypedArray a = context.obtainStyledAttributes(attrs, com.android.internal.R.styleable.View);
     57         mFadingEdgeLength = a.getDimensionPixelSize(android.R.styleable.View_fadingEdgeLength,
     58                 ViewConfiguration.get(context).getScaledFadingEdgeLength());
     59         mIsVertical = isVertical;
     60     }
     61 
     62     public void onAttachedToWindowCallback(
     63             RecentsCallback callback, LinearLayout layout, boolean hardwareAccelerated) {
     64         mSoftwareRendered = !hardwareAccelerated;
     65         if ((mSoftwareRendered && OPTIMIZE_SW_RENDERED_RECENTS)
     66                 || USE_DARK_FADE_IN_HW_ACCELERATED_MODE) {
     67             mScrollView.setVerticalFadingEdgeEnabled(false);
     68             mScrollView.setHorizontalFadingEdgeEnabled(false);
     69         }
     70     }
     71 
     72     public void addViewCallback(View newLinearLayoutChild) {
     73         if (mSoftwareRendered && OPTIMIZE_SW_RENDERED_RECENTS) {
     74             final RecentsPanelView.ViewHolder holder =
     75                     (RecentsPanelView.ViewHolder) newLinearLayoutChild.getTag();
     76             holder.labelView.setDrawingCacheEnabled(true);
     77             holder.labelView.buildDrawingCache();
     78         }
     79     }
     80 
     81     public void drawCallback(Canvas canvas,
     82             int left, int right, int top, int bottom, int scrollX, int scrollY,
     83             float topFadingEdgeStrength, float bottomFadingEdgeStrength,
     84             float leftFadingEdgeStrength, float rightFadingEdgeStrength) {
     85 
     86         if ((mSoftwareRendered && OPTIMIZE_SW_RENDERED_RECENTS)
     87                 || USE_DARK_FADE_IN_HW_ACCELERATED_MODE) {
     88             Paint p = new Paint();
     89             Matrix matrix = new Matrix();
     90             // use use a height of 1, and then wack the matrix each time we
     91             // actually use it.
     92             Shader fade = new LinearGradient(0, 0, 0, 1, 0xCC000000, 0, Shader.TileMode.CLAMP);
     93             // PULL OUT THIS CONSTANT
     94 
     95             p.setShader(fade);
     96 
     97             // draw the fade effect
     98             boolean drawTop = false;
     99             boolean drawBottom = false;
    100             boolean drawLeft = false;
    101             boolean drawRight = false;
    102 
    103             float topFadeStrength = 0.0f;
    104             float bottomFadeStrength = 0.0f;
    105             float leftFadeStrength = 0.0f;
    106             float rightFadeStrength = 0.0f;
    107 
    108             final float fadeHeight = mFadingEdgeLength;
    109             int length = (int) fadeHeight;
    110 
    111             // clip the fade length if top and bottom fades overlap
    112             // overlapping fades produce odd-looking artifacts
    113             if (mIsVertical && (top + length > bottom - length)) {
    114                 length = (bottom - top) / 2;
    115             }
    116 
    117             // also clip horizontal fades if necessary
    118             if (!mIsVertical && (left + length > right - length)) {
    119                 length = (right - left) / 2;
    120             }
    121 
    122             if (mIsVertical) {
    123                 topFadeStrength = Math.max(0.0f, Math.min(1.0f, topFadingEdgeStrength));
    124                 drawTop = topFadeStrength * fadeHeight > 1.0f;
    125                 bottomFadeStrength = Math.max(0.0f, Math.min(1.0f, bottomFadingEdgeStrength));
    126                 drawBottom = bottomFadeStrength * fadeHeight > 1.0f;
    127             }
    128 
    129             if (!mIsVertical) {
    130                 leftFadeStrength = Math.max(0.0f, Math.min(1.0f, leftFadingEdgeStrength));
    131                 drawLeft = leftFadeStrength * fadeHeight > 1.0f;
    132                 rightFadeStrength = Math.max(0.0f, Math.min(1.0f, rightFadingEdgeStrength));
    133                 drawRight = rightFadeStrength * fadeHeight > 1.0f;
    134             }
    135 
    136             if (drawTop) {
    137                 matrix.setScale(1, fadeHeight * topFadeStrength);
    138                 matrix.postTranslate(left, top);
    139                 fade.setLocalMatrix(matrix);
    140                 canvas.drawRect(left, top, right, top + length, p);
    141             }
    142 
    143             if (drawBottom) {
    144                 matrix.setScale(1, fadeHeight * bottomFadeStrength);
    145                 matrix.postRotate(180);
    146                 matrix.postTranslate(left, bottom);
    147                 fade.setLocalMatrix(matrix);
    148                 canvas.drawRect(left, bottom - length, right, bottom, p);
    149             }
    150 
    151             if (drawLeft) {
    152                 matrix.setScale(1, fadeHeight * leftFadeStrength);
    153                 matrix.postRotate(-90);
    154                 matrix.postTranslate(left, top);
    155                 fade.setLocalMatrix(matrix);
    156                 canvas.drawRect(left, top, left + length, bottom, p);
    157             }
    158 
    159             if (drawRight) {
    160                 matrix.setScale(1, fadeHeight * rightFadeStrength);
    161                 matrix.postRotate(90);
    162                 matrix.postTranslate(right, top);
    163                 fade.setLocalMatrix(matrix);
    164                 canvas.drawRect(right - length, top, right, bottom, p);
    165             }
    166         }
    167     }
    168 
    169     public int getVerticalFadingEdgeLengthCallback() {
    170         return mFadingEdgeLength;
    171     }
    172 
    173     public int getHorizontalFadingEdgeLengthCallback() {
    174         return mFadingEdgeLength;
    175     }
    176 
    177 }
    178