131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project/*
231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project
331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project *
431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * you may not use this file except in compliance with the License.
631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * You may obtain a copy of the License at
731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project *
831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project *
1031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
1131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
1231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * See the License for the specific language governing permissions and
1431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * limitations under the License.
1531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */
1631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
17325dc23624160689e59fbac708cf6f222b20d025Daniel Sandlerpackage com.android.launcher3;
1831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
19508da15509224b46fcccabbe78f3e92fe69a67d8Sunny Goyalimport android.animation.ObjectAnimator;
20508da15509224b46fcccabbe78f3e92fe69a67d8Sunny Goyalimport android.animation.TimeInterpolator;
2131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.graphics.Bitmap;
2231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.graphics.Canvas;
23508da15509224b46fcccabbe78f3e92fe69a67d8Sunny Goyalimport android.graphics.Color;
2431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.graphics.ColorFilter;
25c5c60ad3592f53549c9ffaa58e9a87b0480080e8Sunny Goyalimport android.graphics.ColorMatrix;
26c5c60ad3592f53549c9ffaa58e9a87b0480080e8Sunny Goyalimport android.graphics.ColorMatrixColorFilter;
2745e1d6ec0a213a444d01466c3d4f1ded5508ed63Winson Chungimport android.graphics.Paint;
2845e1d6ec0a213a444d01466c3d4f1ded5508ed63Winson Chungimport android.graphics.PixelFormat;
29508da15509224b46fcccabbe78f3e92fe69a67d8Sunny Goyalimport android.graphics.PorterDuff;
30508da15509224b46fcccabbe78f3e92fe69a67d8Sunny Goyalimport android.graphics.PorterDuffColorFilter;
3145e1d6ec0a213a444d01466c3d4f1ded5508ed63Winson Chungimport android.graphics.Rect;
3245e1d6ec0a213a444d01466c3d4f1ded5508ed63Winson Chungimport android.graphics.drawable.Drawable;
33508da15509224b46fcccabbe78f3e92fe69a67d8Sunny Goyalimport android.util.SparseArray;
3431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
3531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectclass FastBitmapDrawable extends Drawable {
36c5c60ad3592f53549c9ffaa58e9a87b0480080e8Sunny Goyal
37508da15509224b46fcccabbe78f3e92fe69a67d8Sunny Goyal    static final TimeInterpolator CLICK_FEEDBACK_INTERPOLATOR = new TimeInterpolator() {
38508da15509224b46fcccabbe78f3e92fe69a67d8Sunny Goyal
39508da15509224b46fcccabbe78f3e92fe69a67d8Sunny Goyal        @Override
40508da15509224b46fcccabbe78f3e92fe69a67d8Sunny Goyal        public float getInterpolation(float input) {
41508da15509224b46fcccabbe78f3e92fe69a67d8Sunny Goyal            if (input < 0.05f) {
42508da15509224b46fcccabbe78f3e92fe69a67d8Sunny Goyal                return input / 0.05f;
43508da15509224b46fcccabbe78f3e92fe69a67d8Sunny Goyal            } else if (input < 0.3f){
44508da15509224b46fcccabbe78f3e92fe69a67d8Sunny Goyal                return 1;
45508da15509224b46fcccabbe78f3e92fe69a67d8Sunny Goyal            } else {
46508da15509224b46fcccabbe78f3e92fe69a67d8Sunny Goyal                return (1 - input) / 0.7f;
47508da15509224b46fcccabbe78f3e92fe69a67d8Sunny Goyal            }
48508da15509224b46fcccabbe78f3e92fe69a67d8Sunny Goyal        }
49508da15509224b46fcccabbe78f3e92fe69a67d8Sunny Goyal    };
50508da15509224b46fcccabbe78f3e92fe69a67d8Sunny Goyal    static final long CLICK_FEEDBACK_DURATION = 2000;
51508da15509224b46fcccabbe78f3e92fe69a67d8Sunny Goyal
52508da15509224b46fcccabbe78f3e92fe69a67d8Sunny Goyal    private static final int PRESSED_BRIGHTNESS = 100;
5395abbb330ce9bbaf23594245f0f8a795c8118038Sunny Goyal    private static ColorMatrix sGhostModeMatrix;
5495abbb330ce9bbaf23594245f0f8a795c8118038Sunny Goyal    private static final ColorMatrix sTempMatrix = new ColorMatrix();
5595abbb330ce9bbaf23594245f0f8a795c8118038Sunny Goyal
56508da15509224b46fcccabbe78f3e92fe69a67d8Sunny Goyal    /**
57508da15509224b46fcccabbe78f3e92fe69a67d8Sunny Goyal     * Store the brightness colors filters to optimize animations during icon press. This
58508da15509224b46fcccabbe78f3e92fe69a67d8Sunny Goyal     * only works for non-ghost-mode icons.
59508da15509224b46fcccabbe78f3e92fe69a67d8Sunny Goyal     */
60508da15509224b46fcccabbe78f3e92fe69a67d8Sunny Goyal    private static final SparseArray<ColorFilter> sCachedBrightnessFilter =
61508da15509224b46fcccabbe78f3e92fe69a67d8Sunny Goyal            new SparseArray<ColorFilter>();
62508da15509224b46fcccabbe78f3e92fe69a67d8Sunny Goyal
6395abbb330ce9bbaf23594245f0f8a795c8118038Sunny Goyal    private static final int GHOST_MODE_MIN_COLOR_RANGE = 130;
64c5c60ad3592f53549c9ffaa58e9a87b0480080e8Sunny Goyal
65c5c60ad3592f53549c9ffaa58e9a87b0480080e8Sunny Goyal    private final Paint mPaint = new Paint(Paint.FILTER_BITMAP_FLAG);
66508da15509224b46fcccabbe78f3e92fe69a67d8Sunny Goyal    private final Bitmap mBitmap;
6729d6fea296ebecb607525c8245a54696ad7c5db7Winson Chung    private int mAlpha;
68c5c60ad3592f53549c9ffaa58e9a87b0480080e8Sunny Goyal
69c5c60ad3592f53549c9ffaa58e9a87b0480080e8Sunny Goyal    private int mBrightness = 0;
7095abbb330ce9bbaf23594245f0f8a795c8118038Sunny Goyal    private boolean mGhostModeEnabled = false;
7131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
72508da15509224b46fcccabbe78f3e92fe69a67d8Sunny Goyal    private boolean mPressed = false;
73508da15509224b46fcccabbe78f3e92fe69a67d8Sunny Goyal    private ObjectAnimator mPressedAnimator;
74508da15509224b46fcccabbe78f3e92fe69a67d8Sunny Goyal
7531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    FastBitmapDrawable(Bitmap b) {
76eeb5bbc9409978cc2ae52d48380399fcde3d9f85Winson Chung        mAlpha = 255;
7731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        mBitmap = b;
78268f1c563f4179ee2fb6c87b662679451e23a7c8Winson Chung        setBounds(0, 0, b.getWidth(), b.getHeight());
7931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
8031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
8131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    @Override
8231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    public void draw(Canvas canvas) {
8345e1d6ec0a213a444d01466c3d4f1ded5508ed63Winson Chung        final Rect r = getBounds();
848a196351ef7e100857e6c6d5b344d1d780584887Winson Chung        // Draw the bitmap into the bounding rect
858a196351ef7e100857e6c6d5b344d1d780584887Winson Chung        canvas.drawBitmap(mBitmap, null, r, mPaint);
8631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
8731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
8831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    @Override
89badf71e11fba2d6efa1d1bcca9542001f90a3777Adam Cohen    public void setColorFilter(ColorFilter cf) {
90c5c60ad3592f53549c9ffaa58e9a87b0480080e8Sunny Goyal        // No op
91badf71e11fba2d6efa1d1bcca9542001f90a3777Adam Cohen    }
92badf71e11fba2d6efa1d1bcca9542001f90a3777Adam Cohen
93badf71e11fba2d6efa1d1bcca9542001f90a3777Adam Cohen    @Override
9431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    public int getOpacity() {
9531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        return PixelFormat.TRANSLUCENT;
9631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
9731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
9831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    @Override
9931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    public void setAlpha(int alpha) {
10029d6fea296ebecb607525c8245a54696ad7c5db7Winson Chung        mAlpha = alpha;
101b3347bb9f4ccf41fb7043bca66c3a565bde1083bWinson Chung        mPaint.setAlpha(alpha);
10231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
10331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
104c5c60ad3592f53549c9ffaa58e9a87b0480080e8Sunny Goyal    @Override
10576fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen    public void setFilterBitmap(boolean filterBitmap) {
10676fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen        mPaint.setFilterBitmap(filterBitmap);
1076e1c0d34bb31cacc24c57c89ab01deaa8985814fWinson Chung        mPaint.setAntiAlias(filterBitmap);
10876fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen    }
10976fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen
11029d6fea296ebecb607525c8245a54696ad7c5db7Winson Chung    public int getAlpha() {
11129d6fea296ebecb607525c8245a54696ad7c5db7Winson Chung        return mAlpha;
11229d6fea296ebecb607525c8245a54696ad7c5db7Winson Chung    }
11329d6fea296ebecb607525c8245a54696ad7c5db7Winson Chung
11431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    @Override
11531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    public int getIntrinsicWidth() {
116c424f2290e96cea419f95c5ccb730a4946824c1bSunny Goyal        return mBitmap.getWidth();
11731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
11831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
11931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    @Override
12031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    public int getIntrinsicHeight() {
121c424f2290e96cea419f95c5ccb730a4946824c1bSunny Goyal        return mBitmap.getHeight();
12231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
12331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
12431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    @Override
12531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    public int getMinimumWidth() {
126eeb5bbc9409978cc2ae52d48380399fcde3d9f85Winson Chung        return getBounds().width();
12731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
12831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
12931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    @Override
13031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    public int getMinimumHeight() {
131eeb5bbc9409978cc2ae52d48380399fcde3d9f85Winson Chung        return getBounds().height();
1320589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato    }
1330589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato
13431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    public Bitmap getBitmap() {
13531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        return mBitmap;
13631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
137c5c60ad3592f53549c9ffaa58e9a87b0480080e8Sunny Goyal
13895abbb330ce9bbaf23594245f0f8a795c8118038Sunny Goyal    /**
13995abbb330ce9bbaf23594245f0f8a795c8118038Sunny Goyal     * When enabled, the icon is grayed out and the contrast is increased to give it a 'ghost'
14095abbb330ce9bbaf23594245f0f8a795c8118038Sunny Goyal     * appearance.
14195abbb330ce9bbaf23594245f0f8a795c8118038Sunny Goyal     */
14295abbb330ce9bbaf23594245f0f8a795c8118038Sunny Goyal    public void setGhostModeEnabled(boolean enabled) {
14395abbb330ce9bbaf23594245f0f8a795c8118038Sunny Goyal        if (mGhostModeEnabled != enabled) {
14495abbb330ce9bbaf23594245f0f8a795c8118038Sunny Goyal            mGhostModeEnabled = enabled;
14595abbb330ce9bbaf23594245f0f8a795c8118038Sunny Goyal            updateFilter();
14695abbb330ce9bbaf23594245f0f8a795c8118038Sunny Goyal        }
147c5c60ad3592f53549c9ffaa58e9a87b0480080e8Sunny Goyal    }
148c5c60ad3592f53549c9ffaa58e9a87b0480080e8Sunny Goyal
149508da15509224b46fcccabbe78f3e92fe69a67d8Sunny Goyal    public void setPressed(boolean pressed) {
150508da15509224b46fcccabbe78f3e92fe69a67d8Sunny Goyal        if (mPressed != pressed) {
151508da15509224b46fcccabbe78f3e92fe69a67d8Sunny Goyal            mPressed = pressed;
152508da15509224b46fcccabbe78f3e92fe69a67d8Sunny Goyal            if (mPressed) {
153508da15509224b46fcccabbe78f3e92fe69a67d8Sunny Goyal                mPressedAnimator = ObjectAnimator
154508da15509224b46fcccabbe78f3e92fe69a67d8Sunny Goyal                        .ofInt(this, "brightness", PRESSED_BRIGHTNESS)
155508da15509224b46fcccabbe78f3e92fe69a67d8Sunny Goyal                        .setDuration(CLICK_FEEDBACK_DURATION);
156508da15509224b46fcccabbe78f3e92fe69a67d8Sunny Goyal                mPressedAnimator.setInterpolator(CLICK_FEEDBACK_INTERPOLATOR);
157508da15509224b46fcccabbe78f3e92fe69a67d8Sunny Goyal                mPressedAnimator.start();
158508da15509224b46fcccabbe78f3e92fe69a67d8Sunny Goyal            } else if (mPressedAnimator != null) {
159508da15509224b46fcccabbe78f3e92fe69a67d8Sunny Goyal                mPressedAnimator.cancel();
160508da15509224b46fcccabbe78f3e92fe69a67d8Sunny Goyal                setBrightness(0);
161508da15509224b46fcccabbe78f3e92fe69a67d8Sunny Goyal            }
162508da15509224b46fcccabbe78f3e92fe69a67d8Sunny Goyal        }
163508da15509224b46fcccabbe78f3e92fe69a67d8Sunny Goyal        invalidateSelf();
164508da15509224b46fcccabbe78f3e92fe69a67d8Sunny Goyal    }
165508da15509224b46fcccabbe78f3e92fe69a67d8Sunny Goyal
16695abbb330ce9bbaf23594245f0f8a795c8118038Sunny Goyal    public boolean isGhostModeEnabled() {
16795abbb330ce9bbaf23594245f0f8a795c8118038Sunny Goyal        return mGhostModeEnabled;
168c5c60ad3592f53549c9ffaa58e9a87b0480080e8Sunny Goyal    }
169c5c60ad3592f53549c9ffaa58e9a87b0480080e8Sunny Goyal
170c5c60ad3592f53549c9ffaa58e9a87b0480080e8Sunny Goyal    public int getBrightness() {
171c5c60ad3592f53549c9ffaa58e9a87b0480080e8Sunny Goyal        return mBrightness;
172c5c60ad3592f53549c9ffaa58e9a87b0480080e8Sunny Goyal    }
173c5c60ad3592f53549c9ffaa58e9a87b0480080e8Sunny Goyal
174c5c60ad3592f53549c9ffaa58e9a87b0480080e8Sunny Goyal    public void setBrightness(int brightness) {
17595abbb330ce9bbaf23594245f0f8a795c8118038Sunny Goyal        if (mBrightness != brightness) {
17695abbb330ce9bbaf23594245f0f8a795c8118038Sunny Goyal            mBrightness = brightness;
17795abbb330ce9bbaf23594245f0f8a795c8118038Sunny Goyal            updateFilter();
178508da15509224b46fcccabbe78f3e92fe69a67d8Sunny Goyal            invalidateSelf();
17995abbb330ce9bbaf23594245f0f8a795c8118038Sunny Goyal        }
180c5c60ad3592f53549c9ffaa58e9a87b0480080e8Sunny Goyal    }
181c5c60ad3592f53549c9ffaa58e9a87b0480080e8Sunny Goyal
182c5c60ad3592f53549c9ffaa58e9a87b0480080e8Sunny Goyal    private void updateFilter() {
18395abbb330ce9bbaf23594245f0f8a795c8118038Sunny Goyal        if (mGhostModeEnabled) {
18495abbb330ce9bbaf23594245f0f8a795c8118038Sunny Goyal            if (sGhostModeMatrix == null) {
18595abbb330ce9bbaf23594245f0f8a795c8118038Sunny Goyal                sGhostModeMatrix = new ColorMatrix();
18695abbb330ce9bbaf23594245f0f8a795c8118038Sunny Goyal                sGhostModeMatrix.setSaturation(0);
18795abbb330ce9bbaf23594245f0f8a795c8118038Sunny Goyal
18895abbb330ce9bbaf23594245f0f8a795c8118038Sunny Goyal                // For ghost mode, set the color range to [GHOST_MODE_MIN_COLOR_RANGE, 255]
18995abbb330ce9bbaf23594245f0f8a795c8118038Sunny Goyal                float range = (255 - GHOST_MODE_MIN_COLOR_RANGE) / 255.0f;
19095abbb330ce9bbaf23594245f0f8a795c8118038Sunny Goyal                sTempMatrix.set(new float[] {
19195abbb330ce9bbaf23594245f0f8a795c8118038Sunny Goyal                        range, 0, 0, 0, GHOST_MODE_MIN_COLOR_RANGE,
19295abbb330ce9bbaf23594245f0f8a795c8118038Sunny Goyal                        0, range, 0, 0, GHOST_MODE_MIN_COLOR_RANGE,
19395abbb330ce9bbaf23594245f0f8a795c8118038Sunny Goyal                        0, 0, range, 0, GHOST_MODE_MIN_COLOR_RANGE,
19495abbb330ce9bbaf23594245f0f8a795c8118038Sunny Goyal                        0, 0, 0, 1, 0 });
19595abbb330ce9bbaf23594245f0f8a795c8118038Sunny Goyal                sGhostModeMatrix.preConcat(sTempMatrix);
19695abbb330ce9bbaf23594245f0f8a795c8118038Sunny Goyal            }
19795abbb330ce9bbaf23594245f0f8a795c8118038Sunny Goyal
19895abbb330ce9bbaf23594245f0f8a795c8118038Sunny Goyal            if (mBrightness == 0) {
19995abbb330ce9bbaf23594245f0f8a795c8118038Sunny Goyal                mPaint.setColorFilter(new ColorMatrixColorFilter(sGhostModeMatrix));
20095abbb330ce9bbaf23594245f0f8a795c8118038Sunny Goyal            } else {
20195abbb330ce9bbaf23594245f0f8a795c8118038Sunny Goyal                setBrightnessMatrix(sTempMatrix, mBrightness);
20295abbb330ce9bbaf23594245f0f8a795c8118038Sunny Goyal                sTempMatrix.postConcat(sGhostModeMatrix);
20395abbb330ce9bbaf23594245f0f8a795c8118038Sunny Goyal                mPaint.setColorFilter(new ColorMatrixColorFilter(sTempMatrix));
204c5c60ad3592f53549c9ffaa58e9a87b0480080e8Sunny Goyal            }
20595abbb330ce9bbaf23594245f0f8a795c8118038Sunny Goyal        } else if (mBrightness != 0) {
206508da15509224b46fcccabbe78f3e92fe69a67d8Sunny Goyal            ColorFilter filter = sCachedBrightnessFilter.get(mBrightness);
207508da15509224b46fcccabbe78f3e92fe69a67d8Sunny Goyal            if (filter == null) {
208508da15509224b46fcccabbe78f3e92fe69a67d8Sunny Goyal                filter = new PorterDuffColorFilter(Color.argb(mBrightness, 255, 255, 255),
209508da15509224b46fcccabbe78f3e92fe69a67d8Sunny Goyal                        PorterDuff.Mode.SRC_ATOP);
210508da15509224b46fcccabbe78f3e92fe69a67d8Sunny Goyal                sCachedBrightnessFilter.put(mBrightness, filter);
211508da15509224b46fcccabbe78f3e92fe69a67d8Sunny Goyal            }
212508da15509224b46fcccabbe78f3e92fe69a67d8Sunny Goyal            mPaint.setColorFilter(filter);
213c5c60ad3592f53549c9ffaa58e9a87b0480080e8Sunny Goyal        } else {
214c5c60ad3592f53549c9ffaa58e9a87b0480080e8Sunny Goyal            mPaint.setColorFilter(null);
215c5c60ad3592f53549c9ffaa58e9a87b0480080e8Sunny Goyal        }
216c5c60ad3592f53549c9ffaa58e9a87b0480080e8Sunny Goyal    }
21795abbb330ce9bbaf23594245f0f8a795c8118038Sunny Goyal
21895abbb330ce9bbaf23594245f0f8a795c8118038Sunny Goyal    private static void setBrightnessMatrix(ColorMatrix matrix, int brightness) {
21995abbb330ce9bbaf23594245f0f8a795c8118038Sunny Goyal        // Brightness: C-new = C-old*(1-amount) + amount
22095abbb330ce9bbaf23594245f0f8a795c8118038Sunny Goyal        float scale = 1 - brightness / 255.0f;
22195abbb330ce9bbaf23594245f0f8a795c8118038Sunny Goyal        matrix.setScale(scale, scale, scale, 1);
22295abbb330ce9bbaf23594245f0f8a795c8118038Sunny Goyal        float[] array = matrix.getArray();
22395abbb330ce9bbaf23594245f0f8a795c8118038Sunny Goyal
22495abbb330ce9bbaf23594245f0f8a795c8118038Sunny Goyal        // Add the amount to RGB components of the matrix, as per the above formula.
22595abbb330ce9bbaf23594245f0f8a795c8118038Sunny Goyal        // Fifth elements in the array correspond to the constant being added to
22695abbb330ce9bbaf23594245f0f8a795c8118038Sunny Goyal        // red, blue, green, and alpha channel respectively.
22795abbb330ce9bbaf23594245f0f8a795c8118038Sunny Goyal        array[4] = brightness;
22895abbb330ce9bbaf23594245f0f8a795c8118038Sunny Goyal        array[9] = brightness;
22995abbb330ce9bbaf23594245f0f8a795c8118038Sunny Goyal        array[14] = brightness;
23095abbb330ce9bbaf23594245f0f8a795c8118038Sunny Goyal    }
23131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project}
232