• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2018 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.charging;
18 
19 import android.animation.AnimatorSet;
20 import android.animation.ObjectAnimator;
21 import android.animation.ValueAnimator;
22 import android.content.Context;
23 import android.graphics.drawable.Animatable;
24 import android.util.AttributeSet;
25 import android.util.TypedValue;
26 import android.view.ContextThemeWrapper;
27 import android.view.animation.PathInterpolator;
28 import android.widget.FrameLayout;
29 import android.widget.ImageView;
30 import android.widget.TextView;
31 
32 import com.android.systemui.Interpolators;
33 import com.android.systemui.R;
34 
35 import java.text.NumberFormat;
36 
37 /**
38  * @hide
39  */
40 public class WirelessChargingLayout extends FrameLayout {
41     public final static int UNKNOWN_BATTERY_LEVEL = -1;
42 
WirelessChargingLayout(Context context)43     public WirelessChargingLayout(Context context) {
44         super(context);
45         init(context, null, false);
46     }
47 
WirelessChargingLayout(Context context, int transmittingBatteryLevel, int batteryLevel, boolean isDozing)48     public WirelessChargingLayout(Context context, int transmittingBatteryLevel, int batteryLevel,
49             boolean isDozing) {
50         super(context);
51         init(context, null, transmittingBatteryLevel, batteryLevel, isDozing);
52     }
53 
WirelessChargingLayout(Context context, AttributeSet attrs)54     public WirelessChargingLayout(Context context, AttributeSet attrs) {
55         super(context, attrs);
56         init(context, attrs, false);
57     }
58 
init(Context c, AttributeSet attrs, boolean isDozing)59     private void init(Context c, AttributeSet attrs, boolean isDozing) {
60         init(c, attrs, -1, -1, false);
61     }
62 
init(Context context, AttributeSet attrs, int transmittingBatteryLevel, int batteryLevel, boolean isDozing)63     private void init(Context context, AttributeSet attrs, int transmittingBatteryLevel,
64             int batteryLevel, boolean isDozing) {
65         final boolean showTransmittingBatteryLevel =
66                 (transmittingBatteryLevel != UNKNOWN_BATTERY_LEVEL);
67 
68         // set style based on background
69         int style = R.style.ChargingAnim_WallpaperBackground;
70         if (isDozing) {
71             style = R.style.ChargingAnim_DarkBackground;
72         }
73 
74         inflate(new ContextThemeWrapper(context, style), R.layout.wireless_charging_layout, this);
75 
76         // where the circle animation occurs:
77         final ImageView chargingView = findViewById(R.id.wireless_charging_view);
78         final Animatable chargingAnimation = (Animatable) chargingView.getDrawable();
79 
80         // amount of battery:
81         final TextView percentage = findViewById(R.id.wireless_charging_percentage);
82 
83         if (batteryLevel != UNKNOWN_BATTERY_LEVEL) {
84             percentage.setText(NumberFormat.getPercentInstance().format(batteryLevel / 100f));
85             percentage.setAlpha(0);
86         }
87 
88         final long chargingAnimationFadeStartOffset = context.getResources().getInteger(
89                 R.integer.wireless_charging_fade_offset);
90         final long chargingAnimationFadeDuration = context.getResources().getInteger(
91                 R.integer.wireless_charging_fade_duration);
92         final float batteryLevelTextSizeStart = context.getResources().getFloat(
93                 R.dimen.wireless_charging_anim_battery_level_text_size_start);
94         final float batteryLevelTextSizeEnd = context.getResources().getFloat(
95                 R.dimen.wireless_charging_anim_battery_level_text_size_end) * (
96                 showTransmittingBatteryLevel ? 0.75f : 1.0f);
97 
98         // Animation Scale: battery percentage text scales from 0% to 100%
99         ValueAnimator textSizeAnimator = ObjectAnimator.ofFloat(percentage, "textSize",
100                 batteryLevelTextSizeStart, batteryLevelTextSizeEnd);
101         textSizeAnimator.setInterpolator(new PathInterpolator(0, 0, 0, 1));
102         textSizeAnimator.setDuration(context.getResources().getInteger(
103                 R.integer.wireless_charging_battery_level_text_scale_animation_duration));
104 
105         // Animation Opacity: battery percentage text transitions from 0 to 1 opacity
106         ValueAnimator textOpacityAnimator = ObjectAnimator.ofFloat(percentage, "alpha", 0, 1);
107         textOpacityAnimator.setInterpolator(Interpolators.LINEAR);
108         textOpacityAnimator.setDuration(context.getResources().getInteger(
109                 R.integer.wireless_charging_battery_level_text_opacity_duration));
110         textOpacityAnimator.setStartDelay(context.getResources().getInteger(
111                 R.integer.wireless_charging_anim_opacity_offset));
112 
113         // Animation Opacity: battery percentage text fades from 1 to 0 opacity
114         ValueAnimator textFadeAnimator = ObjectAnimator.ofFloat(percentage, "alpha", 1, 0);
115         textFadeAnimator.setDuration(chargingAnimationFadeDuration);
116         textFadeAnimator.setInterpolator(Interpolators.LINEAR);
117         textFadeAnimator.setStartDelay(chargingAnimationFadeStartOffset);
118 
119         // play all animations together
120         AnimatorSet animatorSet = new AnimatorSet();
121         animatorSet.playTogether(textSizeAnimator, textOpacityAnimator, textFadeAnimator);
122 
123         if (!showTransmittingBatteryLevel) {
124             chargingAnimation.start();
125             animatorSet.start();
126             return;
127         }
128 
129         // amount of transmitting battery:
130         final TextView transmittingPercentage = findViewById(
131                 R.id.reverse_wireless_charging_percentage);
132         transmittingPercentage.setVisibility(VISIBLE);
133         transmittingPercentage.setText(
134                 NumberFormat.getPercentInstance().format(transmittingBatteryLevel / 100f));
135         transmittingPercentage.setAlpha(0);
136 
137         // Animation Scale: transmitting battery percentage text scales from 0% to 100%
138         ValueAnimator textSizeAnimatorTransmitting = ObjectAnimator.ofFloat(transmittingPercentage,
139                 "textSize", batteryLevelTextSizeStart, batteryLevelTextSizeEnd);
140         textSizeAnimatorTransmitting.setInterpolator(new PathInterpolator(0, 0, 0, 1));
141         textSizeAnimatorTransmitting.setDuration(context.getResources().getInteger(
142                 R.integer.wireless_charging_battery_level_text_scale_animation_duration));
143 
144         // Animation Opacity: transmitting battery percentage text transitions from 0 to 1 opacity
145         ValueAnimator textOpacityAnimatorTransmitting = ObjectAnimator.ofFloat(
146                 transmittingPercentage, "alpha", 0, 1);
147         textOpacityAnimatorTransmitting.setInterpolator(Interpolators.LINEAR);
148         textOpacityAnimatorTransmitting.setDuration(context.getResources().getInteger(
149                 R.integer.wireless_charging_battery_level_text_opacity_duration));
150         textOpacityAnimatorTransmitting.setStartDelay(
151                 context.getResources().getInteger(R.integer.wireless_charging_anim_opacity_offset));
152 
153         // Animation Opacity: transmitting battery percentage text fades from 1 to 0 opacity
154         ValueAnimator textFadeAnimatorTransmitting = ObjectAnimator.ofFloat(transmittingPercentage,
155                 "alpha", 1, 0);
156         textFadeAnimatorTransmitting.setDuration(chargingAnimationFadeDuration);
157         textFadeAnimatorTransmitting.setInterpolator(Interpolators.LINEAR);
158         textFadeAnimatorTransmitting.setStartDelay(chargingAnimationFadeStartOffset);
159 
160         // play all animations together
161         AnimatorSet animatorSetTransmitting = new AnimatorSet();
162         animatorSetTransmitting.playTogether(textSizeAnimatorTransmitting,
163                 textOpacityAnimatorTransmitting, textFadeAnimatorTransmitting);
164 
165         // transmitting battery icon
166         final ImageView chargingViewIcon = findViewById(R.id.reverse_wireless_charging_icon);
167         chargingViewIcon.setVisibility(VISIBLE);
168         final int padding = Math.round(
169                 TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, batteryLevelTextSizeEnd,
170                         getResources().getDisplayMetrics()));
171         chargingViewIcon.setPadding(padding, 0, padding, 0);
172 
173         // Animation Opacity: transmitting battery icon transitions from 0 to 1 opacity
174         ValueAnimator textOpacityAnimatorIcon = ObjectAnimator.ofFloat(chargingViewIcon, "alpha", 0,
175                 1);
176         textOpacityAnimatorIcon.setInterpolator(Interpolators.LINEAR);
177         textOpacityAnimatorIcon.setDuration(context.getResources().getInteger(
178                 R.integer.wireless_charging_battery_level_text_opacity_duration));
179         textOpacityAnimatorIcon.setStartDelay(
180                 context.getResources().getInteger(R.integer.wireless_charging_anim_opacity_offset));
181 
182         // Animation Opacity: transmitting battery icon fades from 1 to 0 opacity
183         ValueAnimator textFadeAnimatorIcon = ObjectAnimator.ofFloat(chargingViewIcon, "alpha", 1,
184                 0);
185         textFadeAnimatorIcon.setDuration(chargingAnimationFadeDuration);
186         textFadeAnimatorIcon.setInterpolator(Interpolators.LINEAR);
187         textFadeAnimatorIcon.setStartDelay(chargingAnimationFadeStartOffset);
188 
189         // play all animations together
190         AnimatorSet animatorSetIcon = new AnimatorSet();
191         animatorSetIcon.playTogether(textOpacityAnimatorIcon, textFadeAnimatorIcon);
192 
193         chargingAnimation.start();
194         animatorSet.start();
195         animatorSetTransmitting.start();
196         animatorSetIcon.start();
197     }
198 }
199