blob: cb17ac62439ac08c30318b334120e64f85c0ff0e [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 Spurlock3b139a92013-08-17 17:18:08 -040040 public static final int MODE_OPAQUE = 0;
John Spurlock89835dd2013-08-16 15:06:51 -040041 public static final int MODE_SEMI_TRANSPARENT = 1;
John Spurlockbd957402013-10-03 11:38:39 -040042 public static final int MODE_TRANSLUCENT = 2;
John Spurlock7edfbca2013-09-14 11:58:55 -040043 public static final int MODE_LIGHTS_OUT = 3;
44
John Spurlocke631b412013-09-18 16:33:57 -040045 public static final int LIGHTS_IN_DURATION = 250;
46 public static final int LIGHTS_OUT_DURATION = 750;
47 public static final int BACKGROUND_DURATION = 200;
John Spurlocke932e302013-08-12 10:16:29 -040048
John Spurlock27735a42013-08-14 17:57:38 -040049 private final String mTag;
John Spurlocke631b412013-09-18 16:33:57 -040050 private final View mView;
51 private final boolean mSupportsTransitions = ActivityManager.isHighEndGfx();
John Spurlock42197262013-10-21 09:32:25 -040052 private final BarBackgroundDrawable mBarBackground;
John Spurlocke631b412013-09-18 16:33:57 -040053
John Spurlocke932e302013-08-12 10:16:29 -040054 private int mMode;
John Spurlock3b139a92013-08-17 17:18:08 -040055
John Spurlock7057d2c2013-10-02 10:00:37 -040056 public BarTransitions(View view, int gradientResourceId) {
John Spurlocke631b412013-09-18 16:33:57 -040057 mTag = "BarTransitions." + view.getClass().getSimpleName();
58 mView = view;
John Spurlock42197262013-10-21 09:32:25 -040059 mBarBackground = new BarBackgroundDrawable(mView.getContext(), gradientResourceId);
John Spurlocke631b412013-09-18 16:33:57 -040060 if (mSupportsTransitions) {
John Spurlock42197262013-10-21 09:32:25 -040061 mView.setBackground(mBarBackground);
John Spurlocke631b412013-09-18 16:33:57 -040062 }
63 }
64
John Spurlockb77edbf2013-08-21 21:04:12 -040065 public int getMode() {
66 return mMode;
67 }
68
John Spurlock3b139a92013-08-17 17:18:08 -040069 public void transitionTo(int mode, boolean animate) {
John Spurlock89835dd2013-08-16 15:06:51 -040070 if (mMode == mode) return;
71 int oldMode = mMode;
John Spurlocke932e302013-08-12 10:16:29 -040072 mMode = mode;
John Spurlocke631b412013-09-18 16:33:57 -040073 if (DEBUG) Log.d(mTag, String.format("%s -> %s animate=%s",
74 modeToString(oldMode), modeToString(mode), animate));
75 if (mSupportsTransitions) {
76 onTransition(oldMode, mMode, animate);
77 }
John Spurlock89835dd2013-08-16 15:06:51 -040078 }
79
John Spurlock3b139a92013-08-17 17:18:08 -040080 protected void onTransition(int oldMode, int newMode, boolean animate) {
John Spurlocke631b412013-09-18 16:33:57 -040081 applyModeBackground(oldMode, newMode, animate);
82 }
83
84 protected void applyModeBackground(int oldMode, int newMode, boolean animate) {
John Spurlock42197262013-10-21 09:32:25 -040085 if (DEBUG) Log.d(mTag, String.format("applyModeBackground oldMode=%s newMode=%s animate=%s",
86 modeToString(oldMode), modeToString(newMode), animate));
87 mBarBackground.applyModeBackground(oldMode, newMode, animate);
John Spurlocke932e302013-08-12 10:16:29 -040088 }
John Spurlock27735a42013-08-14 17:57:38 -040089
90 public static String modeToString(int mode) {
John Spurlock3b139a92013-08-17 17:18:08 -040091 if (mode == MODE_OPAQUE) return "MODE_OPAQUE";
John Spurlock89835dd2013-08-16 15:06:51 -040092 if (mode == MODE_SEMI_TRANSPARENT) return "MODE_SEMI_TRANSPARENT";
John Spurlockbd957402013-10-03 11:38:39 -040093 if (mode == MODE_TRANSLUCENT) return "MODE_TRANSLUCENT";
John Spurlock7edfbca2013-09-14 11:58:55 -040094 if (mode == MODE_LIGHTS_OUT) return "MODE_LIGHTS_OUT";
John Spurlock27735a42013-08-14 17:57:38 -040095 throw new IllegalArgumentException("Unknown mode " + mode);
96 }
John Spurlock42197262013-10-21 09:32:25 -040097
98 public void finishAnimations() {
99 mBarBackground.finishAnimation();
100 }
101
John Spurlock56d007b2013-10-28 18:40:56 -0400102 public void setContentVisible(boolean visible) {
103 // for subclasses
104 }
105
John Spurlock42197262013-10-21 09:32:25 -0400106 private static class BarBackgroundDrawable extends Drawable {
107 private final int mOpaque;
108 private final int mSemiTransparent;
109 private final Drawable mGradient;
110 private final TimeInterpolator mInterpolator;
111
112 private int mMode = -1;
113 private boolean mAnimating;
114 private long mStartTime;
115 private long mEndTime;
116
117 private int mGradientAlpha;
118 private int mColor;
119
120 private int mGradientAlphaStart;
121 private int mColorStart;
122
123 public BarBackgroundDrawable(Context context, int gradientResourceId) {
124 final Resources res = context.getResources();
125 if (DEBUG_COLORS) {
126 mOpaque = 0xff0000ff;
127 mSemiTransparent = 0x7f0000ff;
128 } else {
129 mOpaque = res.getColor(R.color.system_bar_background_opaque);
130 mSemiTransparent = res.getColor(R.color.system_bar_background_semi_transparent);
131 }
132 mGradient = res.getDrawable(gradientResourceId);
133 mInterpolator = new LinearInterpolator();
134 }
135
136 @Override
137 public void setAlpha(int alpha) {
138 // noop
139 }
140
141 @Override
142 public void setColorFilter(ColorFilter cf) {
143 // noop
144 }
145
146 @Override
147 protected void onBoundsChange(Rect bounds) {
148 super.onBoundsChange(bounds);
149 mGradient.setBounds(bounds);
150 }
151
152 public void applyModeBackground(int oldMode, int newMode, boolean animate) {
153 if (mMode == newMode) return;
154 mMode = newMode;
155 mAnimating = animate;
156 if (animate) {
157 long now = SystemClock.elapsedRealtime();
158 mStartTime = now;
159 mEndTime = now + BACKGROUND_DURATION;
160 mGradientAlphaStart = mGradientAlpha;
161 mColorStart = mColor;
162 }
163 invalidateSelf();
164 }
165
166 @Override
167 public int getOpacity() {
168 return PixelFormat.TRANSLUCENT;
169 }
170
171 public void finishAnimation() {
172 if (mAnimating) {
173 mAnimating = false;
174 invalidateSelf();
175 }
176 }
177
178 @Override
179 public void draw(Canvas canvas) {
180 int targetGradientAlpha = 0, targetColor = 0;
181 if (mMode == MODE_TRANSLUCENT) {
182 targetGradientAlpha = 0xff;
183 } else if (mMode == MODE_SEMI_TRANSPARENT) {
184 targetColor = mSemiTransparent;
185 } else {
186 targetColor = mOpaque;
187 }
188 if (!mAnimating) {
189 mColor = targetColor;
190 mGradientAlpha = targetGradientAlpha;
191 } else {
192 final long now = SystemClock.elapsedRealtime();
193 if (now >= mEndTime) {
194 mAnimating = false;
195 mColor = targetColor;
196 mGradientAlpha = targetGradientAlpha;
197 } else {
198 final float t = (now - mStartTime) / (float)(mEndTime - mStartTime);
199 final float v = Math.max(0, Math.min(mInterpolator.getInterpolation(t), 1));
200 mGradientAlpha = (int)(v * targetGradientAlpha + mGradientAlphaStart * (1 - v));
201 mColor = Color.argb(
202 (int)(v * Color.alpha(targetColor) + Color.alpha(mColorStart) * (1 - v)),
203 (int)(v * Color.red(targetColor) + Color.red(mColorStart) * (1 - v)),
204 (int)(v * Color.green(targetColor) + Color.green(mColorStart) * (1 - v)),
205 (int)(v * Color.blue(targetColor) + Color.blue(mColorStart) * (1 - v)));
206 }
207 }
208 if (mGradientAlpha > 0) {
209 mGradient.setAlpha(mGradientAlpha);
210 mGradient.draw(canvas);
211 }
212 if (Color.alpha(mColor) > 0) {
213 canvas.drawColor(mColor);
214 }
215 if (mAnimating) {
216 invalidateSelf(); // keep going
217 }
218 }
219 }
John Spurlocke932e302013-08-12 10:16:29 -0400220}