1 /*
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 
17 package com.android.systemui.statusbar.phone;
18 
19 import android.animation.Animator;
20 import android.animation.AnimatorSet;
21 import android.animation.ObjectAnimator;
22 import android.content.res.Resources;
23 import android.view.View;
24 
25 import com.android.systemui.R;
26 
27 public final class PhoneStatusBarTransitions extends BarTransitions {
28     private static final float ICON_ALPHA_WHEN_NOT_OPAQUE = 1;
29     private static final float ICON_ALPHA_WHEN_LIGHTS_OUT_BATTERY_CLOCK = 0.5f;
30     private static final float ICON_ALPHA_WHEN_LIGHTS_OUT_NON_BATTERY_CLOCK = 0;
31 
32     private final float mIconAlphaWhenOpaque;
33 
34     private boolean mIsHeadsUp;
35 
36     private View mStartSide, mStatusIcons, mBattery;
37     private Animator mCurrentAnimation;
38 
39     /**
40      * @param backgroundView view to apply the background drawable
41      */
PhoneStatusBarTransitions(PhoneStatusBarView statusBarView, View backgroundView)42     public PhoneStatusBarTransitions(PhoneStatusBarView statusBarView, View backgroundView) {
43         super(backgroundView, R.drawable.status_background);
44         final Resources res = statusBarView.getContext().getResources();
45         mIconAlphaWhenOpaque = res.getFraction(R.dimen.status_bar_icon_drawing_alpha, 1, 1);
46         mStartSide = statusBarView.findViewById(R.id.status_bar_start_side_except_heads_up);
47         mStatusIcons = statusBarView.findViewById(R.id.statusIcons);
48         mBattery = statusBarView.findViewById(R.id.battery);
49         applyModeBackground(-1, getMode(), false /*animate*/);
50         applyMode(getMode(), false /*animate*/);
51     }
52 
animateTransitionTo(View v, float toAlpha)53     public ObjectAnimator animateTransitionTo(View v, float toAlpha) {
54         return ObjectAnimator.ofFloat(v, "alpha", v.getAlpha(), toAlpha);
55     }
56 
getStatusIconsAlphaFor(int mode)57     private float getStatusIconsAlphaFor(int mode) {
58         return getDefaultAlphaFor(mode);
59     }
60 
getStartSideAlphaFor(int mode)61     private float getStartSideAlphaFor(int mode) {
62         // When there's a heads up notification, we need the start side icons to show regardless of
63         // lights out mode.
64         if (mIsHeadsUp) {
65             return getIconAlphaBasedOnOpacity(mode);
66         }
67         return getDefaultAlphaFor(mode);
68     }
69 
getBatteryClockAlpha(int mode)70     private float getBatteryClockAlpha(int mode) {
71         return isLightsOut(mode) ? ICON_ALPHA_WHEN_LIGHTS_OUT_BATTERY_CLOCK
72                 : getIconAlphaBasedOnOpacity(mode);
73     }
74 
getDefaultAlphaFor(int mode)75     private float getDefaultAlphaFor(int mode) {
76         return isLightsOut(mode) ? ICON_ALPHA_WHEN_LIGHTS_OUT_NON_BATTERY_CLOCK
77                 : getIconAlphaBasedOnOpacity(mode);
78     }
79 
getIconAlphaBasedOnOpacity(int mode)80     private float getIconAlphaBasedOnOpacity(int mode) {
81         return !isOpaque(mode) ? ICON_ALPHA_WHEN_NOT_OPAQUE
82                 : mIconAlphaWhenOpaque;
83     }
84 
isOpaque(int mode)85     private boolean isOpaque(int mode) {
86         return !(mode == MODE_SEMI_TRANSPARENT || mode == MODE_TRANSLUCENT
87                 || mode == MODE_TRANSPARENT || mode == MODE_LIGHTS_OUT_TRANSPARENT);
88     }
89 
90     @Override
onTransition(int oldMode, int newMode, boolean animate)91     protected void onTransition(int oldMode, int newMode, boolean animate) {
92         super.onTransition(oldMode, newMode, animate);
93         applyMode(newMode, animate);
94     }
95 
96     /** Informs this controller that the heads up notification state has changed. */
onHeadsUpStateChanged(boolean isHeadsUp)97     public void onHeadsUpStateChanged(boolean isHeadsUp) {
98         mIsHeadsUp = isHeadsUp;
99         // We want the icon to be fully visible when the HUN appears, so just immediately change the
100         // icon visibility and don't animate.
101         applyMode(getMode(), /* animate= */ false);
102     }
103 
applyMode(int mode, boolean animate)104     private void applyMode(int mode, boolean animate) {
105         if (mStartSide == null) return; // pre-init
106         float newStartSideAlpha = getStartSideAlphaFor(mode);
107         float newStatusIconsAlpha = getStatusIconsAlphaFor(mode);
108         float newBatteryAlpha = getBatteryClockAlpha(mode);
109         if (mCurrentAnimation != null) {
110             mCurrentAnimation.cancel();
111         }
112         if (animate) {
113             AnimatorSet anims = new AnimatorSet();
114             anims.playTogether(
115                     animateTransitionTo(mStartSide, newStartSideAlpha),
116                     animateTransitionTo(mStatusIcons, newStatusIconsAlpha),
117                     animateTransitionTo(mBattery, newBatteryAlpha)
118                     );
119             if (isLightsOut(mode)) {
120                 anims.setDuration(LIGHTS_OUT_DURATION);
121             }
122             anims.start();
123             mCurrentAnimation = anims;
124         } else {
125             mStartSide.setAlpha(newStartSideAlpha);
126             mStatusIcons.setAlpha(newStatusIconsAlpha);
127             mBattery.setAlpha(newBatteryAlpha);
128         }
129     }
130 }
131