blob: 5796edbeea619b1bab6e558f7b188a7bd4f01596 [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
19import android.app.ActivityManager;
John Spurlock42197262013-10-21 09:32:25 -040020import android.content.Context;
John Spurlocke932e302013-08-12 10:16:29 -040021import android.content.res.Resources;
John Spurlock42197262013-10-21 09:32:25 -040022import android.graphics.Canvas;
23import android.graphics.Color;
24import android.graphics.ColorFilter;
25import android.graphics.PixelFormat;
26import android.graphics.Rect;
John Spurlocke932e302013-08-12 10:16:29 -040027import android.graphics.drawable.Drawable;
John Spurlock42197262013-10-21 09:32:25 -040028import android.os.SystemClock;
John Spurlock27735a42013-08-14 17:57:38 -040029import android.util.Log;
John Spurlocke932e302013-08-12 10:16:29 -040030import android.view.View;
31
Winsonc0d70582016-01-29 10:24:39 -080032import com.android.systemui.Interpolators;
John Spurlocke932e302013-08-12 10:16:29 -040033import com.android.systemui.R;
34
35public class BarTransitions {
John Spurlock27735a42013-08-14 17:57:38 -040036 private static final boolean DEBUG = false;
John Spurlocke631b412013-09-18 16:33:57 -040037 private static final boolean DEBUG_COLORS = false;
John Spurlocke932e302013-08-12 10:16:29 -040038
John Spurlockfd0e6c02014-01-14 14:51:23 -050039 public static final boolean HIGH_END = ActivityManager.isHighEndGfx();
40
John Spurlock3b139a92013-08-17 17:18:08 -040041 public static final int MODE_OPAQUE = 0;
John Spurlock89835dd2013-08-16 15:06:51 -040042 public static final int MODE_SEMI_TRANSPARENT = 1;
John Spurlockbd957402013-10-03 11:38:39 -040043 public static final int MODE_TRANSLUCENT = 2;
John Spurlock7edfbca2013-09-14 11:58:55 -040044 public static final int MODE_LIGHTS_OUT = 3;
Adrian Roosea562512014-05-05 13:33:03 +020045 public static final int MODE_TRANSPARENT = 4;
John Spurlock0ff62e02014-07-22 16:15:08 -040046 public static final int MODE_WARNING = 5;
Adrian Roosc0f0a742014-10-28 16:39:56 +010047 public static final int MODE_LIGHTS_OUT_TRANSPARENT = 6;
John Spurlock7edfbca2013-09-14 11:58:55 -040048
John Spurlocke631b412013-09-18 16:33:57 -040049 public static final int LIGHTS_IN_DURATION = 250;
50 public static final int LIGHTS_OUT_DURATION = 750;
51 public static final int BACKGROUND_DURATION = 200;
John Spurlocke932e302013-08-12 10:16:29 -040052
John Spurlock27735a42013-08-14 17:57:38 -040053 private final String mTag;
John Spurlocke631b412013-09-18 16:33:57 -040054 private final View mView;
John Spurlock42197262013-10-21 09:32:25 -040055 private final BarBackgroundDrawable mBarBackground;
John Spurlocke631b412013-09-18 16:33:57 -040056
John Spurlocke932e302013-08-12 10:16:29 -040057 private int mMode;
John Spurlock3b139a92013-08-17 17:18:08 -040058
John Spurlock7057d2c2013-10-02 10:00:37 -040059 public BarTransitions(View view, int gradientResourceId) {
John Spurlocke631b412013-09-18 16:33:57 -040060 mTag = "BarTransitions." + view.getClass().getSimpleName();
61 mView = view;
John Spurlock42197262013-10-21 09:32:25 -040062 mBarBackground = new BarBackgroundDrawable(mView.getContext(), gradientResourceId);
John Spurlockfd0e6c02014-01-14 14:51:23 -050063 if (HIGH_END) {
John Spurlock42197262013-10-21 09:32:25 -040064 mView.setBackground(mBarBackground);
John Spurlocke631b412013-09-18 16:33:57 -040065 }
66 }
67
John Spurlockb77edbf2013-08-21 21:04:12 -040068 public int getMode() {
69 return mMode;
70 }
71
John Spurlock3b139a92013-08-17 17:18:08 -040072 public void transitionTo(int mode, boolean animate) {
John Spurlockfd0e6c02014-01-14 14:51:23 -050073 // low-end devices do not support translucent modes, fallback to opaque
Adrian Roosea562512014-05-05 13:33:03 +020074 if (!HIGH_END && (mode == MODE_SEMI_TRANSPARENT || mode == MODE_TRANSLUCENT
75 || mode == MODE_TRANSPARENT)) {
John Spurlockfd0e6c02014-01-14 14:51:23 -050076 mode = MODE_OPAQUE;
77 }
Adrian Roosc0f0a742014-10-28 16:39:56 +010078 if (!HIGH_END && (mode == MODE_LIGHTS_OUT_TRANSPARENT)) {
79 mode = MODE_LIGHTS_OUT;
80 }
John Spurlock89835dd2013-08-16 15:06:51 -040081 if (mMode == mode) return;
82 int oldMode = mMode;
John Spurlocke932e302013-08-12 10:16:29 -040083 mMode = mode;
John Spurlocke631b412013-09-18 16:33:57 -040084 if (DEBUG) Log.d(mTag, String.format("%s -> %s animate=%s",
85 modeToString(oldMode), modeToString(mode), animate));
John Spurlockfd0e6c02014-01-14 14:51:23 -050086 onTransition(oldMode, mMode, animate);
John Spurlock89835dd2013-08-16 15:06:51 -040087 }
88
John Spurlock3b139a92013-08-17 17:18:08 -040089 protected void onTransition(int oldMode, int newMode, boolean animate) {
John Spurlockfd0e6c02014-01-14 14:51:23 -050090 if (HIGH_END) {
91 applyModeBackground(oldMode, newMode, animate);
92 }
John Spurlocke631b412013-09-18 16:33:57 -040093 }
94
95 protected void applyModeBackground(int oldMode, int newMode, boolean animate) {
John Spurlock42197262013-10-21 09:32:25 -040096 if (DEBUG) Log.d(mTag, String.format("applyModeBackground oldMode=%s newMode=%s animate=%s",
97 modeToString(oldMode), modeToString(newMode), animate));
98 mBarBackground.applyModeBackground(oldMode, newMode, animate);
John Spurlocke932e302013-08-12 10:16:29 -040099 }
John Spurlock27735a42013-08-14 17:57:38 -0400100
101 public static String modeToString(int mode) {
John Spurlock3b139a92013-08-17 17:18:08 -0400102 if (mode == MODE_OPAQUE) return "MODE_OPAQUE";
John Spurlock89835dd2013-08-16 15:06:51 -0400103 if (mode == MODE_SEMI_TRANSPARENT) return "MODE_SEMI_TRANSPARENT";
John Spurlockbd957402013-10-03 11:38:39 -0400104 if (mode == MODE_TRANSLUCENT) return "MODE_TRANSLUCENT";
John Spurlock7edfbca2013-09-14 11:58:55 -0400105 if (mode == MODE_LIGHTS_OUT) return "MODE_LIGHTS_OUT";
Adrian Roosea562512014-05-05 13:33:03 +0200106 if (mode == MODE_TRANSPARENT) return "MODE_TRANSPARENT";
John Spurlock0ff62e02014-07-22 16:15:08 -0400107 if (mode == MODE_WARNING) return "MODE_WARNING";
Adrian Roosc0f0a742014-10-28 16:39:56 +0100108 if (mode == MODE_LIGHTS_OUT_TRANSPARENT) return "MODE_LIGHTS_OUT_TRANSPARENT";
John Spurlock27735a42013-08-14 17:57:38 -0400109 throw new IllegalArgumentException("Unknown mode " + mode);
110 }
John Spurlock42197262013-10-21 09:32:25 -0400111
112 public void finishAnimations() {
113 mBarBackground.finishAnimation();
114 }
115
Adrian Roosc0f0a742014-10-28 16:39:56 +0100116 protected boolean isLightsOut(int mode) {
117 return mode == MODE_LIGHTS_OUT || mode == MODE_LIGHTS_OUT_TRANSPARENT;
118 }
119
John Spurlock42197262013-10-21 09:32:25 -0400120 private static class BarBackgroundDrawable extends Drawable {
121 private final int mOpaque;
122 private final int mSemiTransparent;
Adrian Roosea562512014-05-05 13:33:03 +0200123 private final int mTransparent;
John Spurlock0ff62e02014-07-22 16:15:08 -0400124 private final int mWarning;
John Spurlock42197262013-10-21 09:32:25 -0400125 private final Drawable mGradient;
John Spurlock42197262013-10-21 09:32:25 -0400126
127 private int mMode = -1;
128 private boolean mAnimating;
129 private long mStartTime;
130 private long mEndTime;
131
132 private int mGradientAlpha;
133 private int mColor;
134
135 private int mGradientAlphaStart;
136 private int mColorStart;
137
138 public BarBackgroundDrawable(Context context, int gradientResourceId) {
139 final Resources res = context.getResources();
140 if (DEBUG_COLORS) {
141 mOpaque = 0xff0000ff;
142 mSemiTransparent = 0x7f0000ff;
Adrian Roosea562512014-05-05 13:33:03 +0200143 mTransparent = 0x2f0000ff;
John Spurlock0ff62e02014-07-22 16:15:08 -0400144 mWarning = 0xffff0000;
John Spurlock42197262013-10-21 09:32:25 -0400145 } else {
Alan Viverette4a357cd2015-03-18 18:37:18 -0700146 mOpaque = context.getColor(R.color.system_bar_background_opaque);
Jorim Jaggi4fa78922015-11-30 17:13:56 -0800147 mSemiTransparent = context.getColor(
148 com.android.internal.R.color.system_bar_background_semi_transparent);
Alan Viverette4a357cd2015-03-18 18:37:18 -0700149 mTransparent = context.getColor(R.color.system_bar_background_transparent);
150 mWarning = context.getColor(com.android.internal.R.color.battery_saver_mode_color);
John Spurlock42197262013-10-21 09:32:25 -0400151 }
Alan Viverette4a357cd2015-03-18 18:37:18 -0700152 mGradient = context.getDrawable(gradientResourceId);
John Spurlock42197262013-10-21 09:32:25 -0400153 }
154
155 @Override
156 public void setAlpha(int alpha) {
157 // noop
158 }
159
160 @Override
Chris Craikbd3bfc52015-03-02 10:43:29 -0800161 public void setColorFilter(ColorFilter colorFilter) {
John Spurlock42197262013-10-21 09:32:25 -0400162 // noop
163 }
164
165 @Override
166 protected void onBoundsChange(Rect bounds) {
167 super.onBoundsChange(bounds);
168 mGradient.setBounds(bounds);
169 }
170
171 public void applyModeBackground(int oldMode, int newMode, boolean animate) {
172 if (mMode == newMode) return;
173 mMode = newMode;
174 mAnimating = animate;
175 if (animate) {
176 long now = SystemClock.elapsedRealtime();
177 mStartTime = now;
178 mEndTime = now + BACKGROUND_DURATION;
179 mGradientAlphaStart = mGradientAlpha;
180 mColorStart = mColor;
181 }
182 invalidateSelf();
183 }
184
185 @Override
186 public int getOpacity() {
187 return PixelFormat.TRANSLUCENT;
188 }
189
190 public void finishAnimation() {
191 if (mAnimating) {
192 mAnimating = false;
193 invalidateSelf();
194 }
195 }
196
197 @Override
198 public void draw(Canvas canvas) {
199 int targetGradientAlpha = 0, targetColor = 0;
John Spurlock0ff62e02014-07-22 16:15:08 -0400200 if (mMode == MODE_WARNING) {
201 targetColor = mWarning;
202 } else if (mMode == MODE_TRANSLUCENT) {
Adrian Roosea562512014-05-05 13:33:03 +0200203 targetColor = mSemiTransparent;
John Spurlock42197262013-10-21 09:32:25 -0400204 } else if (mMode == MODE_SEMI_TRANSPARENT) {
205 targetColor = mSemiTransparent;
Adrian Roosc0f0a742014-10-28 16:39:56 +0100206 } else if (mMode == MODE_TRANSPARENT || mMode == MODE_LIGHTS_OUT_TRANSPARENT) {
Adrian Roosea562512014-05-05 13:33:03 +0200207 targetColor = mTransparent;
John Spurlock42197262013-10-21 09:32:25 -0400208 } else {
209 targetColor = mOpaque;
210 }
211 if (!mAnimating) {
212 mColor = targetColor;
213 mGradientAlpha = targetGradientAlpha;
214 } else {
215 final long now = SystemClock.elapsedRealtime();
216 if (now >= mEndTime) {
217 mAnimating = false;
218 mColor = targetColor;
219 mGradientAlpha = targetGradientAlpha;
220 } else {
221 final float t = (now - mStartTime) / (float)(mEndTime - mStartTime);
Selim Cinekc18010f2016-01-20 13:41:30 -0800222 final float v = Math.max(0, Math.min(
223 Interpolators.LINEAR.getInterpolation(t), 1));
John Spurlock42197262013-10-21 09:32:25 -0400224 mGradientAlpha = (int)(v * targetGradientAlpha + mGradientAlphaStart * (1 - v));
225 mColor = Color.argb(
226 (int)(v * Color.alpha(targetColor) + Color.alpha(mColorStart) * (1 - v)),
227 (int)(v * Color.red(targetColor) + Color.red(mColorStart) * (1 - v)),
228 (int)(v * Color.green(targetColor) + Color.green(mColorStart) * (1 - v)),
229 (int)(v * Color.blue(targetColor) + Color.blue(mColorStart) * (1 - v)));
230 }
231 }
232 if (mGradientAlpha > 0) {
233 mGradient.setAlpha(mGradientAlpha);
234 mGradient.draw(canvas);
235 }
236 if (Color.alpha(mColor) > 0) {
237 canvas.drawColor(mColor);
238 }
239 if (mAnimating) {
240 invalidateSelf(); // keep going
241 }
242 }
243 }
John Spurlocke932e302013-08-12 10:16:29 -0400244}