New AOD battery indicator

Moves battery indication from the bottom of the screen
to the top right.

Bug: 111405682
Change-Id: If241451c45108c95176db7be18ae7033091a3432
Fixes: 80113947
Test: visual
This commit is contained in:
Lucas Dupin
2018-09-20 13:41:46 -07:00
parent 1bbbc4de68
commit 7da4f26bdf
8 changed files with 139 additions and 94 deletions

View File

@@ -650,7 +650,6 @@
<dimen name="keyguard_affordance_icon_width">24dp</dimen>
<dimen name="keyguard_indication_margin_bottom">65dp</dimen>
<dimen name="keyguard_indication_margin_bottom_ambient">16dp</dimen>
<!-- The text size for battery level -->
<dimen name="battery_level_text_size">12sp</dimen>
@@ -939,9 +938,8 @@
burn-in on AOD. -->
<dimen name="burn_in_prevention_offset_y">50dp</dimen>
<!-- The maximum offset in either direction that the charging indication moves vertically
to prevent burn-in on AOD. -->
<dimen name="charging_indication_burn_in_prevention_offset_y">5dp</dimen>
<!-- The maximum offset in either direction that icons move to prevent burn-in on AOD. -->
<dimen name="default_burn_in_prevention_offset">5dp</dimen>
<dimen name="corner_size">8dp</dimen>
<dimen name="top_padding">0dp</dimen>

View File

@@ -0,0 +1,51 @@
/*
* Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License
*/
package com.android.systemui.doze.util
import android.util.MathUtils
private const val MILLIS_PER_MINUTES = 1000 * 60f
private const val BURN_IN_PREVENTION_PERIOD_Y = 521f
private const val BURN_IN_PREVENTION_PERIOD_X = 83f
/**
* Returns the translation offset that should be used to avoid burn in at
* the current time (in pixels.)
*
* @param amplitude Maximum translation that will be interpolated.
* @param xAxis If we're moving on X or Y.
*/
fun getBurnInOffset(amplitude: Int, xAxis: Boolean): Int {
return zigzag(System.currentTimeMillis() / MILLIS_PER_MINUTES,
amplitude.toFloat(),
if (xAxis) BURN_IN_PREVENTION_PERIOD_X else BURN_IN_PREVENTION_PERIOD_Y).toInt()
}
/**
* Implements a continuous, piecewise linear, periodic zig-zag function
*
* Can be thought of as a linear approximation of abs(sin(x)))
*
* @param period period of the function, ie. zigzag(x + period) == zigzag(x)
* @param amplitude maximum value of the function
* @return a value between 0 and amplitude
*/
private fun zigzag(x: Float, amplitude: Float, period: Float): Float {
val xprime = x % period / (period / 2)
val interpolationAmount = if (xprime <= 1) xprime else 2 - xprime
return MathUtils.lerp(0f, amplitude, interpolationAmount)
}

View File

@@ -298,27 +298,6 @@ public class KeyguardIndicationController {
if (mVisible) {
// Walk down a precedence-ordered list of what indication
// should be shown based on user or device state
if (mDozing) {
mTextView.setTextColor(Color.WHITE);
if (!TextUtils.isEmpty(mTransientIndication)) {
// When dozing we ignore any text color and use white instead, because
// colors can be hard to read in low brightness.
mTextView.switchIndication(mTransientIndication);
} else if (mPowerPluggedIn) {
String indication = computePowerIndication();
if (animate) {
animateText(mTextView, indication);
} else {
mTextView.switchIndication(indication);
}
} else {
String percentage = NumberFormat.getPercentInstance()
.format(mBatteryLevel / 100f);
mTextView.switchIndication(percentage);
}
return;
}
KeyguardUpdateMonitor updateMonitor = KeyguardUpdateMonitor.getInstance(mContext);
int userId = KeyguardUpdateMonitor.getCurrentUser();
String trustGrantedIndication = getTrustGrantedIndication();

View File

@@ -19,6 +19,7 @@ package com.android.systemui.statusbar.phone;
import static android.view.accessibility.AccessibilityNodeInfo.ACTION_CLICK;
import static android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
import static com.android.systemui.doze.util.BurnInHelperKt.getBurnInOffset;
import static com.android.systemui.tuner.LockscreenFragment.LOCKSCREEN_LEFT_BUTTON;
import static com.android.systemui.tuner.LockscreenFragment.LOCKSCREEN_LEFT_UNLOCK;
import static com.android.systemui.tuner.LockscreenFragment.LOCKSCREEN_RIGHT_BUTTON;
@@ -171,7 +172,6 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
private LockscreenGestureLogger mLockscreenGestureLogger = new LockscreenGestureLogger();
private boolean mDozing;
private int mIndicationBottomMargin;
private int mIndicationBottomMarginAmbient;
private float mDarkAmount;
private int mBurnInXOffset;
private int mBurnInYOffset;
@@ -246,10 +246,8 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
mIndicationText = findViewById(R.id.keyguard_indication_text);
mIndicationBottomMargin = getResources().getDimensionPixelSize(
R.dimen.keyguard_indication_margin_bottom);
mIndicationBottomMarginAmbient = getResources().getDimensionPixelSize(
R.dimen.keyguard_indication_margin_bottom_ambient);
mBurnInYOffset = getResources().getDimensionPixelSize(
R.dimen.charging_indication_burn_in_prevention_offset_y);
R.dimen.default_burn_in_prevention_offset);
updateCameraVisibility();
mUnlockMethodCache = UnlockMethodCache.getInstance(getContext());
mUnlockMethodCache.addListener(this);
@@ -320,10 +318,8 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
super.onConfigurationChanged(newConfig);
mIndicationBottomMargin = getResources().getDimensionPixelSize(
R.dimen.keyguard_indication_margin_bottom);
mIndicationBottomMarginAmbient = getResources().getDimensionPixelSize(
R.dimen.keyguard_indication_margin_bottom_ambient);
mBurnInYOffset = getResources().getDimensionPixelSize(
R.dimen.charging_indication_burn_in_prevention_offset_y);
R.dimen.default_burn_in_prevention_offset);
MarginLayoutParams mlp = (MarginLayoutParams) mIndicationArea.getLayoutParams();
if (mlp.bottomMargin != mIndicationBottomMargin) {
mlp.bottomMargin = mIndicationBottomMargin;
@@ -567,9 +563,7 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
return;
}
mDarkAmount = darkAmount;
mIndicationArea.setAlpha(MathUtils.lerp(1f, 0.7f, darkAmount));
mIndicationArea.setTranslationY(MathUtils.lerp(0,
mIndicationBottomMargin - mIndicationBottomMarginAmbient, darkAmount));
mIndicationArea.setAlpha(1f - darkAmount);
}
private static boolean isSuccessfulLaunch(int result) {
@@ -842,10 +836,10 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
public void dozeTimeTick() {
if (mDarkAmount == 1) {
// Move indication every minute to avoid burn-in
int dozeTranslation = mIndicationBottomMargin - mIndicationBottomMarginAmbient;
int burnInYOffset = (int) (-mBurnInYOffset + Math.random() * mBurnInYOffset * 2);
mIndicationArea.setTranslationY(dozeTranslation + burnInYOffset);
// Move views every minute to avoid burn-in
int burnInYOffset = getBurnInOffset(mBurnInYOffset * 2, false /* xAxis */)
- mBurnInYOffset;
mLockIcon.setTranslationY(burnInYOffset);
}
}
@@ -854,7 +848,7 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
return;
}
mBurnInXOffset = burnInXOffset;
mIndicationArea.setTranslationX(burnInXOffset);
mLockIcon.setTranslationX(burnInXOffset);
}
private class DefaultLeftButton implements IntentButton {

View File

@@ -16,6 +16,7 @@
package com.android.systemui.statusbar.phone;
import static com.android.systemui.doze.util.BurnInHelperKt.getBurnInOffset;
import static com.android.systemui.statusbar.notification.NotificationUtils.interpolate;
import android.content.res.Resources;
@@ -30,10 +31,6 @@ import com.android.systemui.R;
*/
public class KeyguardClockPositionAlgorithm {
private static final long MILLIS_PER_MINUTES = 1000 * 60;
private static final float BURN_IN_PREVENTION_PERIOD_Y = 521;
private static final float BURN_IN_PREVENTION_PERIOD_X = 83;
/**
* How much the clock height influences the shade position.
* 0 means nothing, 1 means move the shade up by the height of the clock
@@ -228,34 +225,15 @@ public class KeyguardClockPositionAlgorithm {
}
private float burnInPreventionOffsetY() {
return zigzag(System.currentTimeMillis() / MILLIS_PER_MINUTES,
mBurnInPreventionOffsetY * 2,
BURN_IN_PREVENTION_PERIOD_Y)
return getBurnInOffset(mBurnInPreventionOffsetY * 2, false /* xAxis */)
- mBurnInPreventionOffsetY;
}
private float burnInPreventionOffsetX() {
return zigzag(System.currentTimeMillis() / MILLIS_PER_MINUTES,
mBurnInPreventionOffsetX * 2,
BURN_IN_PREVENTION_PERIOD_X)
return getBurnInOffset(mBurnInPreventionOffsetX * 2, true /* xAxis */)
- mBurnInPreventionOffsetX;
}
/**
* Implements a continuous, piecewise linear, periodic zig-zag function
*
* Can be thought of as a linear approximation of abs(sin(x)))
*
* @param period period of the function, ie. zigzag(x + period) == zigzag(x)
* @param amplitude maximum value of the function
* @return a value between 0 and amplitude
*/
private float zigzag(float x, float amplitude, float period) {
float xprime = (x % period) / (period / 2);
float interpolationAmount = (xprime <= 1) ? xprime : (2 - xprime);
return interpolate(0, amplitude, interpolationAmount);
}
public static class Result {
/**

View File

@@ -17,6 +17,7 @@
package com.android.systemui.statusbar.phone;
import static com.android.systemui.ScreenDecorations.DisplayCutoutView.boundsFromDirection;
import static com.android.systemui.doze.util.BurnInHelperKt.getBurnInOffset;
import android.annotation.ColorInt;
import android.content.Context;
@@ -70,16 +71,18 @@ public class KeyguardStatusBarView extends RelativeLayout
private static final int LAYOUT_CUTOUT = 1;
private static final int LAYOUT_NO_CUTOUT = 2;
private final Rect mEmptyRect = new Rect(0, 0, 0, 0);
private boolean mShowPercentAvailable;
private boolean mBatteryCharging;
private boolean mKeyguardUserSwitcherShowing;
private boolean mBatteryListening;
private TextView mCarrierLabel;
private View mSystemIconsSuperContainer;
private MultiUserSwitch mMultiUserSwitch;
private ImageView mMultiUserAvatar;
private BatteryMeterView mBatteryView;
private StatusIconContainer mStatusIconContainer;
private BatteryController mBatteryController;
private KeyguardUserSwitcher mKeyguardUserSwitcher;
@@ -99,6 +102,18 @@ public class KeyguardStatusBarView extends RelativeLayout
*/
private int mCutoutSideNudge = 0;
/**
* How much to move icons to avoid burn in.
*/
private int mBurnInOffset;
private int mCurrentBurnInOffsetX;
private int mCurrentBurnInOffsetY;
/**
* Ratio representing being in ambient mode or not.
*/
private float mDarkAmount;
public KeyguardStatusBarView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@@ -113,6 +128,7 @@ public class KeyguardStatusBarView extends RelativeLayout
mBatteryView = mSystemIconsContainer.findViewById(R.id.battery);
mCutoutSpace = findViewById(R.id.cutout_space_view);
mStatusIconArea = findViewById(R.id.status_icon_area);
mStatusIconContainer = findViewById(R.id.statusIcons);
loadDimens();
updateUserSwitcher();
@@ -169,6 +185,8 @@ public class KeyguardStatusBarView extends RelativeLayout
R.dimen.system_icons_super_container_avatarless_margin_end);
mCutoutSideNudge = getResources().getDimensionPixelSize(
R.dimen.display_cutout_margin_consumption);
mBurnInOffset = getResources().getDimensionPixelSize(
R.dimen.default_burn_in_prevention_offset);
mShowPercentAvailable = getContext().getResources().getBoolean(
com.android.internal.R.bool.config_battery_percentage_setting_available);
}
@@ -440,6 +458,14 @@ public class KeyguardStatusBarView extends RelativeLayout
}
public void onThemeChanged() {
mBatteryView.setColorsFromContext(mContext);
updateIconsAndTextColors();
// Reload user avatar
((UserInfoControllerImpl) Dependency.get(UserInfoController.class))
.onDensityOrFontScaleChanged();
}
private void updateIconsAndTextColors() {
@ColorInt int textColor = Utils.getColorAttrDefaultColor(mContext,
R.attr.wallpaperTextColor);
@ColorInt int iconColor = Utils.getColorStateListDefaultColor(mContext,
@@ -448,14 +474,9 @@ public class KeyguardStatusBarView extends RelativeLayout
float intensity = textColor == Color.WHITE ? 0 : 1;
mCarrierLabel.setTextColor(iconColor);
mIconManager.setTint(iconColor);
mBatteryView.setColorsFromContext(mContext);
Rect tintArea = new Rect(0, 0, 0, 0);
applyDarkness(R.id.battery, tintArea, intensity, iconColor);
applyDarkness(R.id.clock, tintArea, intensity, iconColor);
// Reload user avatar
((UserInfoControllerImpl) Dependency.get(UserInfoController.class))
.onDensityOrFontScaleChanged();
applyDarkness(R.id.battery, mEmptyRect, intensity * (1f - mDarkAmount), iconColor);
applyDarkness(R.id.clock, mEmptyRect, intensity, iconColor);
}
private void applyDarkness(int id, Rect tintArea, float intensity, int color) {
@@ -475,4 +496,32 @@ public class KeyguardStatusBarView extends RelativeLayout
mBatteryView.dump(fd, pw, args);
}
}
public void setDarkAmount(float darkAmount) {
mDarkAmount = darkAmount;
if (darkAmount == 0) {
dozeTimeTick();
}
updateDozeState();
}
public void dozeTimeTick() {
mCurrentBurnInOffsetX = getBurnInOffset(mBurnInOffset, true /* xAxis */);
mCurrentBurnInOffsetY = getBurnInOffset(mBurnInOffset, false /* xAxis */);
updateDozeState();
}
private void updateDozeState() {
float alpha = 1f - mDarkAmount;
int visibility = alpha != 0f ? VISIBLE : INVISIBLE;
mCarrierLabel.setAlpha(alpha);
mCarrierLabel.setVisibility(visibility);
mStatusIconContainer.setAlpha(alpha);
mStatusIconContainer.setVisibility(visibility);
mSystemIconsContainer.setTranslationX(-mCurrentBurnInOffsetX * mDarkAmount);
mSystemIconsContainer.setTranslationY(mCurrentBurnInOffsetY * mDarkAmount);
updateIconsAndTextColors();
}
}

View File

@@ -63,6 +63,7 @@ import com.android.systemui.classifier.FalsingManager;
import com.android.systemui.fragments.FragmentHostManager;
import com.android.systemui.fragments.FragmentHostManager.FragmentListener;
import com.android.systemui.plugins.qs.QS;
import com.android.systemui.qs.QSFragment;
import com.android.systemui.statusbar.FlingAnimationUtils;
import com.android.systemui.statusbar.GestureRecorder;
import com.android.systemui.statusbar.KeyguardAffordanceView;
@@ -455,6 +456,10 @@ public class NotificationPanelView extends PanelView implements
initBottomArea();
setDarkAmount(mLinearDarkAmount, mInterpolatedDarkAmount);
if (mKeyguardStatusBar != null) {
mKeyguardStatusBar.onThemeChanged();
}
setKeyguardStatusViewVisibility(mBarState, false, false);
setKeyguardBottomAreaVisibility(mBarState, false);
}
@@ -1836,10 +1841,10 @@ public class NotificationPanelView extends PanelView implements
return;
}
float alphaQsExpansion = 1 - Math.min(1, getQsExpansionFraction() * 2);
mKeyguardStatusBar.setAlpha(Math.min(getKeyguardContentsAlpha(), alphaQsExpansion)
* mKeyguardStatusBarAnimateAlpha);
mKeyguardStatusBar.setVisibility(mKeyguardStatusBar.getAlpha() != 0f
&& !mDozing ? VISIBLE : INVISIBLE);
float newAlpha = Math.min(getKeyguardContentsAlpha(), alphaQsExpansion)
* mKeyguardStatusBarAnimateAlpha;
mKeyguardStatusBar.setAlpha(newAlpha);
mKeyguardStatusBar.setVisibility(newAlpha != 0f ? VISIBLE : INVISIBLE);
}
private void updateKeyguardBottomAreaAlpha() {
@@ -2347,16 +2352,7 @@ public class NotificationPanelView extends PanelView implements
}
private void updateDozingVisibilities(boolean animate) {
if (mDozing) {
mKeyguardStatusBar.setVisibility(View.INVISIBLE);
mKeyguardBottomArea.setDozing(mDozing, animate);
} else {
mKeyguardStatusBar.setVisibility(View.VISIBLE);
mKeyguardBottomArea.setDozing(mDozing, animate);
if (animate) {
animateKeyguardStatusBarIn(DOZE_ANIMATION_DURATION);
}
}
mKeyguardBottomArea.setDozing(mDozing, animate);
}
@Override
@@ -2749,6 +2745,9 @@ public class NotificationPanelView extends PanelView implements
}
});
mNotificationStackScroller.setQsContainer((ViewGroup) mQs.getView());
if (mQs instanceof QSFragment) {
mKeyguardStatusBar.setQSPanel(((QSFragment) mQs).getQsPanel());
}
updateQsExpansion();
}
@@ -2811,6 +2810,7 @@ public class NotificationPanelView extends PanelView implements
private void setDarkAmount(float linearAmount, float amount) {
mInterpolatedDarkAmount = amount;
mLinearDarkAmount = linearAmount;
mKeyguardStatusBar.setDarkAmount(mInterpolatedDarkAmount);
mKeyguardStatusView.setDarkAmount(mInterpolatedDarkAmount);
mKeyguardBottomArea.setDarkAmount(mInterpolatedDarkAmount);
positionClockAndNotifications();
@@ -2837,6 +2837,7 @@ public class NotificationPanelView extends PanelView implements
}
public void dozeTimeTick() {
mKeyguardStatusBar.dozeTimeTick();
mKeyguardStatusView.dozeTimeTick();
mKeyguardBottomArea.dozeTimeTick();
if (mInterpolatedDarkAmount > 0) {

View File

@@ -381,8 +381,6 @@ public class StatusBar extends SystemUI implements DemoMode,
// settings
private QSPanel mQSPanel;
// top bar
private KeyguardStatusBarView mKeyguardStatusBar;
KeyguardIndicationController mKeyguardIndicationController;
// RemoteInputView to be activated after unlock
@@ -805,7 +803,6 @@ public class StatusBar extends SystemUI implements DemoMode,
mAboveShelfObserver = new AboveShelfObserver(mStackScroller);
mAboveShelfObserver.setListener(mStatusBarWindow.findViewById(
R.id.notification_container_parent));
mKeyguardStatusBar = mStatusBarWindow.findViewById(R.id.keyguard_header);
mNotificationIconAreaController = SystemUIFactory.getInstance()
.createNotificationIconAreaController(context, this);
@@ -980,7 +977,6 @@ public class StatusBar extends SystemUI implements DemoMode,
((QSFragment) qs).setHost(qsh);
mQSPanel = ((QSFragment) qs).getQsPanel();
mQSPanel.setBrightnessMirror(mBrightnessMirrorController);
mKeyguardStatusBar.setQSPanel(mQSPanel);
}
});
}
@@ -1118,8 +1114,6 @@ public class StatusBar extends SystemUI implements DemoMode,
@Override
public void onThemeChanged() {
// The status bar on the keyguard is a special layout.
if (mKeyguardStatusBar != null) mKeyguardStatusBar.onThemeChanged();
// Recreate Indication controller because internal references changed
mKeyguardIndicationController =
SystemUIFactory.getInstance().createKeyguardIndicationController(mContext,
@@ -1154,7 +1148,8 @@ public class StatusBar extends SystemUI implements DemoMode,
protected void createUserSwitcher() {
mKeyguardUserSwitcher = new KeyguardUserSwitcher(mContext,
mStatusBarWindow.findViewById(R.id.keyguard_user_switcher), mKeyguardStatusBar,
mStatusBarWindow.findViewById(R.id.keyguard_user_switcher),
mStatusBarWindow.findViewById(R.id.keyguard_header),
mNotificationPanel);
}