blob: eb63a548ac428ae608e4d7e1546edd2b7e0d78b6 [file] [log] [blame]
John Spurlocke932e302013-08-12 10:16:29 -04001/*
2 * Copyright (C) 2013 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
17package com.android.systemui.statusbar.phone;
18
John Spurlock42197262013-10-21 09:32:25 -040019import android.animation.TimeInterpolator;
John Spurlocke932e302013-08-12 10:16:29 -040020import android.app.ActivityManager;
John Spurlock42197262013-10-21 09:32:25 -040021import android.content.Context;
John Spurlocke932e302013-08-12 10:16:29 -040022import android.content.res.Resources;
John Spurlock42197262013-10-21 09:32:25 -040023import android.graphics.Canvas;
24import android.graphics.Color;
25import android.graphics.ColorFilter;
26import android.graphics.PixelFormat;
27import android.graphics.Rect;
John Spurlocke932e302013-08-12 10:16:29 -040028import android.graphics.drawable.Drawable;
John Spurlock42197262013-10-21 09:32:25 -040029import android.os.SystemClock;
John Spurlock27735a42013-08-14 17:57:38 -040030import android.util.Log;
John Spurlocke932e302013-08-12 10:16:29 -040031import android.view.View;
John Spurlock42197262013-10-21 09:32:25 -040032import android.view.animation.LinearInterpolator;
John Spurlocke932e302013-08-12 10:16:29 -040033
34import com.android.systemui.R;
35
36public class BarTransitions {
John Spurlock27735a42013-08-14 17:57:38 -040037 private static final boolean DEBUG = false;
John Spurlocke631b412013-09-18 16:33:57 -040038 private static final boolean DEBUG_COLORS = false;
John Spurlocke932e302013-08-12 10:16:29 -040039
John Spurlockfd0e6c02014-01-14 14:51:23 -050040 public static final boolean HIGH_END = ActivityManager.isHighEndGfx();
41
John Spurlock3b139a92013-08-17 17:18:08 -040042 public static final int MODE_OPAQUE = 0;
John Spurlock89835dd2013-08-16 15:06:51 -040043 public static final int MODE_SEMI_TRANSPARENT = 1;
John Spurlockbd957402013-10-03 11:38:39 -040044 public static final int MODE_TRANSLUCENT = 2;
John Spurlock7edfbca2013-09-14 11:58:55 -040045 public static final int MODE_LIGHTS_OUT = 3;
46
John Spurlocke631b412013-09-18 16:33:57 -040047 public static final int LIGHTS_IN_DURATION = 250;
48 public static final int LIGHTS_OUT_DURATION = 750;
49 public static final int BACKGROUND_DURATION = 200;
John Spurlocke932e302013-08-12 10:16:29 -040050
John Spurlock27735a42013-08-14 17:57:38 -040051 private final String mTag;
John Spurlocke631b412013-09-18 16:33:57 -040052 private final View mView;
John Spurlock42197262013-10-21 09:32:25 -040053 private final BarBackgroundDrawable mBarBackground;
John Spurlocke631b412013-09-18 16:33:57 -040054
John Spurlocke932e302013-08-12 10:16:29 -040055 private int mMode;
John Spurlock3b139a92013-08-17 17:18:08 -040056
John Spurlock7057d2c2013-10-02 10:00:37 -040057 public BarTransitions(View view, int gradientResourceId) {
John Spurlocke631b412013-09-18 16:33:57 -040058 mTag = "BarTransitions." + view.getClass().getSimpleName();
59 mView = view;
John Spurlock42197262013-10-21 09:32:25 -040060 mBarBackground = new BarBackgroundDrawable(mView.getContext(), gradientResourceId);
John Spurlockfd0e6c02014-01-14 14:51:23 -050061 if (HIGH_END) {
John Spurlock42197262013-10-21 09:32:25 -040062 mView.setBackground(mBarBackground);
John Spurlocke631b412013-09-18 16:33:57 -040063 }
64 }
65
John Spurlockb77edbf2013-08-21 21:04:12 -040066 public int getMode() {
67 return mMode;
68 }
69
John Spurlock3b139a92013-08-17 17:18:08 -040070 public void transitionTo(int mode, boolean animate) {
John Spurlockfd0e6c02014-01-14 14:51:23 -050071 // low-end devices do not support translucent modes, fallback to opaque
72 if (!HIGH_END && (mode == MODE_SEMI_TRANSPARENT || mode == MODE_TRANSLUCENT)) {
73 mode = MODE_OPAQUE;
74 }
John Spurlock89835dd2013-08-16 15:06:51 -040075 if (mMode == mode) return;
76 int oldMode = mMode;
John Spurlocke932e302013-08-12 10:16:29 -040077 mMode = mode;
John Spurlocke631b412013-09-18 16:33:57 -040078 if (DEBUG) Log.d(mTag, String.format("%s -> %s animate=%s",
79 modeToString(oldMode), modeToString(mode), animate));
John Spurlockfd0e6c02014-01-14 14:51:23 -050080 onTransition(oldMode, mMode, animate);
John Spurlock89835dd2013-08-16 15:06:51 -040081 }
82
John Spurlock3b139a92013-08-17 17:18:08 -040083 protected void onTransition(int oldMode, int newMode, boolean animate) {
John Spurlockfd0e6c02014-01-14 14:51:23 -050084 if (HIGH_END) {
85 applyModeBackground(oldMode, newMode, animate);
86 }
John Spurlocke631b412013-09-18 16:33:57 -040087 }
88
89 protected void applyModeBackground(int oldMode, int newMode, boolean animate) {
John Spurlock42197262013-10-21 09:32:25 -040090 if (DEBUG) Log.d(mTag, String.format("applyModeBackground oldMode=%s newMode=%s animate=%s",
91 modeToString(oldMode), modeToString(newMode), animate));
92 mBarBackground.applyModeBackground(oldMode, newMode, animate);
John Spurlocke932e302013-08-12 10:16:29 -040093 }
John Spurlock27735a42013-08-14 17:57:38 -040094
95 public static String modeToString(int mode) {
John Spurlock3b139a92013-08-17 17:18:08 -040096 if (mode == MODE_OPAQUE) return "MODE_OPAQUE";
John Spurlock89835dd2013-08-16 15:06:51 -040097 if (mode == MODE_SEMI_TRANSPARENT) return "MODE_SEMI_TRANSPARENT";
John Spurlockbd957402013-10-03 11:38:39 -040098 if (mode == MODE_TRANSLUCENT) return "MODE_TRANSLUCENT";
John Spurlock7edfbca2013-09-14 11:58:55 -040099 if (mode == MODE_LIGHTS_OUT) return "MODE_LIGHTS_OUT";
John Spurlock27735a42013-08-14 17:57:38 -0400100 throw new IllegalArgumentException("Unknown mode " + mode);
101 }
John Spurlock42197262013-10-21 09:32:25 -0400102
103 public void finishAnimations() {
104 mBarBackground.finishAnimation();
105 }
106
John Spurlock56d007b2013-10-28 18:40:56 -0400107 public void setContentVisible(boolean visible) {
108 // for subclasses
109 }
110
John Spurlock42197262013-10-21 09:32:25 -0400111 private static class BarBackgroundDrawable extends Drawable {
112 private final int mOpaque;
113 private final int mSemiTransparent;
114 private final Drawable mGradient;
115 private final TimeInterpolator mInterpolator;
116
117 private int mMode = -1;
118 private boolean mAnimating;
119 private long mStartTime;
120 private long mEndTime;
121
122 private int mGradientAlpha;
123 private int mColor;
124
125 private int mGradientAlphaStart;
126 private int mColorStart;
127
128 public BarBackgroundDrawable(Context context, int gradientResourceId) {
129 final Resources res = context.getResources();
130 if (DEBUG_COLORS) {
131 mOpaque = 0xff0000ff;
132 mSemiTransparent = 0x7f0000ff;
133 } else {
134 mOpaque = res.getColor(R.color.system_bar_background_opaque);
135 mSemiTransparent = res.getColor(R.color.system_bar_background_semi_transparent);
136 }
137 mGradient = res.getDrawable(gradientResourceId);
138 mInterpolator = new LinearInterpolator();
139 }
140
141 @Override
142 public void setAlpha(int alpha) {
143 // noop
144 }
145
146 @Override
147 public void setColorFilter(ColorFilter cf) {
148 // noop
149 }
150
151 @Override
152 protected void onBoundsChange(Rect bounds) {
153 super.onBoundsChange(bounds);
154 mGradient.setBounds(bounds);
155 }
156
157 public void applyModeBackground(int oldMode, int newMode, boolean animate) {
158 if (mMode == newMode) return;
159 mMode = newMode;
160 mAnimating = animate;
161 if (animate) {
162 long now = SystemClock.elapsedRealtime();
163 mStartTime = now;
164 mEndTime = now + BACKGROUND_DURATION;
165 mGradientAlphaStart = mGradientAlpha;
166 mColorStart = mColor;
167 }
168 invalidateSelf();
169 }
170
171 @Override
172 public int getOpacity() {
173 return PixelFormat.TRANSLUCENT;
174 }
175
176 public void finishAnimation() {
177 if (mAnimating) {
178 mAnimating = false;
179 invalidateSelf();
180 }
181 }
182
183 @Override
184 public void draw(Canvas canvas) {
185 int targetGradientAlpha = 0, targetColor = 0;
186 if (mMode == MODE_TRANSLUCENT) {
187 targetGradientAlpha = 0xff;
188 } else if (mMode == MODE_SEMI_TRANSPARENT) {
189 targetColor = mSemiTransparent;
190 } else {
191 targetColor = mOpaque;
192 }
193 if (!mAnimating) {
194 mColor = targetColor;
195 mGradientAlpha = targetGradientAlpha;
196 } else {
197 final long now = SystemClock.elapsedRealtime();
198 if (now >= mEndTime) {
199 mAnimating = false;
200 mColor = targetColor;
201 mGradientAlpha = targetGradientAlpha;
202 } else {
203 final float t = (now - mStartTime) / (float)(mEndTime - mStartTime);
204 final float v = Math.max(0, Math.min(mInterpolator.getInterpolation(t), 1));
205 mGradientAlpha = (int)(v * targetGradientAlpha + mGradientAlphaStart * (1 - v));
206 mColor = Color.argb(
207 (int)(v * Color.alpha(targetColor) + Color.alpha(mColorStart) * (1 - v)),
208 (int)(v * Color.red(targetColor) + Color.red(mColorStart) * (1 - v)),
209 (int)(v * Color.green(targetColor) + Color.green(mColorStart) * (1 - v)),
210 (int)(v * Color.blue(targetColor) + Color.blue(mColorStart) * (1 - v)));
211 }
212 }
213 if (mGradientAlpha > 0) {
214 mGradient.setAlpha(mGradientAlpha);
215 mGradient.draw(canvas);
216 }
217 if (Color.alpha(mColor) > 0) {
218 canvas.drawColor(mColor);
219 }
220 if (mAnimating) {
221 invalidateSelf(); // keep going
222 }
223 }
224 }
John Spurlocke932e302013-08-12 10:16:29 -0400225}