Promote lights-out to a bar transition mode.

Move all visual application of the legacy lights-out behind
a new mode managed by BarTransitions for better coordination.

Remove unused "hidden" state in NavigationBarView.

Improve window state (showing/hiding/hidden) calculation,
affecting whether or not sysui thinks it should animate.
Removes invalid interim mode changes causing needless
flashing during some transitions.

Consider WINDOW_STATE_HIDING a state in which we ought to animate,
since at least part of the window is visible throughout.

Make the status/nav bar transition helper classes real boys.

Animate KeyButtonView drawing alpha transition, cancel existing
animations when resetting to avoid needless and unsightly "recovery".

Bug:10746803
Change-Id: Ibd883da9041d071b6a4ff5b42cf96efba7696e9c
This commit is contained in:
John Spurlock
2013-09-14 11:58:55 -04:00
parent 276e6c7a89
commit 7edfbca5d0
8 changed files with 344 additions and 306 deletions

View File

@ -20,7 +20,6 @@ import android.animation.ArgbEvaluator;
import android.animation.ValueAnimator;
import android.animation.ValueAnimator.AnimatorUpdateListener;
import android.app.ActivityManager;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
@ -35,6 +34,10 @@ public class BarTransitions {
public static final int MODE_OPAQUE = 0;
public static final int MODE_SEMI_TRANSPARENT = 1;
public static final int MODE_TRANSPARENT = 2;
public static final int MODE_LIGHTS_OUT = 3;
protected static final int LIGHTS_IN_DURATION = 250;
protected static final int LIGHTS_OUT_DURATION = 750;
private final String mTag;
protected final View mTarget;
@ -52,10 +55,10 @@ public class BarTransitions {
}
};
public BarTransitions(Context context, View target) {
public BarTransitions(View target) {
mTag = "BarTransitions." + target.getClass().getSimpleName();
mTarget = target;
final Resources res = context.getResources();
final Resources res = target.getContext().getResources();
mOpaque = res.getColor(R.drawable.status_bar_background);
mSemiTransparent = res.getColor(R.color.status_bar_background_semi_transparent);
}
@ -76,6 +79,7 @@ public class BarTransitions {
protected Integer getBackgroundColor(int mode) {
if (mode == MODE_SEMI_TRANSPARENT) return mSemiTransparent;
if (mode == MODE_OPAQUE) return mOpaque;
if (mode == MODE_LIGHTS_OUT) return mOpaque;
return null;
}
@ -113,6 +117,7 @@ public class BarTransitions {
if (mode == MODE_OPAQUE) return "MODE_OPAQUE";
if (mode == MODE_SEMI_TRANSPARENT) return "MODE_SEMI_TRANSPARENT";
if (mode == MODE_TRANSPARENT) return "MODE_TRANSPARENT";
if (mode == MODE_LIGHTS_OUT) return "MODE_LIGHTS_OUT";
throw new IllegalArgumentException("Unknown mode " + mode);
}
}

View File

@ -0,0 +1,163 @@
/*
* Copyright (C) 2013 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.statusbar.phone;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.GradientDrawable;
import android.graphics.drawable.GradientDrawable.Orientation;
import android.os.ServiceManager;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.AccelerateInterpolator;
import com.android.internal.statusbar.IStatusBarService;
import com.android.systemui.R;
import com.android.systemui.statusbar.policy.KeyButtonView;
public final class NavigationBarTransitions extends BarTransitions {
private static final boolean ENABLE_GRADIENT = false; // until we can smooth transition
private final NavigationBarView mView;
private final Drawable mTransparentBottom;
private final Drawable mTransparentRight;
private final int mTransparentColor;
private final IStatusBarService mBarService;
private boolean mLightsOut;
public NavigationBarTransitions(NavigationBarView view) {
super(view);
mView = view;
final Resources res = mView.getContext().getResources();
final int[] gradientColors = new int[] {
res.getColor(R.color.navigation_bar_background_transparent_start),
res.getColor(R.color.navigation_bar_background_transparent_end)
};
mTransparentBottom = new GradientDrawable(Orientation.BOTTOM_TOP, gradientColors);
mTransparentRight = new GradientDrawable(Orientation.RIGHT_LEFT, gradientColors);
mTransparentColor = res.getColor(R.color.status_bar_background_transparent);
mBarService = IStatusBarService.Stub.asInterface(
ServiceManager.getService(Context.STATUS_BAR_SERVICE));
}
public void setVertical(boolean isVertical) {
if (!ENABLE_GRADIENT) return;
mTransparent = isVertical ? mTransparentRight : mTransparentBottom;
}
@Override
protected Integer getBackgroundColor(int mode) {
if (!ENABLE_GRADIENT && mode == MODE_TRANSPARENT) return mTransparentColor;
return super.getBackgroundColor(mode);
}
@Override
protected void onTransition(int oldMode, int newMode, boolean animate) {
super.onTransition(oldMode, newMode, animate);
applyMode(newMode, animate, false /*force*/);
}
public void reapplyMode() {
applyMode(getMode(), false /*animate*/, true /*force*/);
}
private void applyMode(int mode, boolean animate, boolean force) {
// apply to key buttons
final boolean isOpaque = mode == MODE_OPAQUE || mode == MODE_LIGHTS_OUT;
final float alpha = isOpaque ? KeyButtonView.DEFAULT_QUIESCENT_ALPHA : 1f;
setKeyButtonViewQuiescentAlpha(mView.getBackButton(), alpha, animate);
setKeyButtonViewQuiescentAlpha(mView.getHomeButton(), alpha, animate);
setKeyButtonViewQuiescentAlpha(mView.getRecentsButton(), alpha, animate);
setKeyButtonViewQuiescentAlpha(mView.getMenuButton(), alpha, animate);
// apply to lights out
applyLightsOut(mode == MODE_LIGHTS_OUT, animate, force);
}
private void setKeyButtonViewQuiescentAlpha(View button, float alpha, boolean animate) {
if (button instanceof KeyButtonView) {
((KeyButtonView) button).setQuiescentAlpha(alpha, animate);
}
}
private void applyLightsOut(boolean lightsOut, boolean animate, boolean force) {
if (!force && lightsOut == mLightsOut) return;
mLightsOut = lightsOut;
final View navButtons = mView.getCurrentView().findViewById(R.id.nav_buttons);
final View lowLights = mView.getCurrentView().findViewById(R.id.lights_out);
// ok, everyone, stop it right there
navButtons.animate().cancel();
lowLights.animate().cancel();
final float navButtonsAlpha = lightsOut ? 0f : 1f;
final float lowLightsAlpha = lightsOut ? 1f : 0f;
if (!animate) {
navButtons.setAlpha(navButtonsAlpha);
lowLights.setAlpha(lowLightsAlpha);
lowLights.setVisibility(lightsOut ? View.VISIBLE : View.GONE);
} else {
final int duration = lightsOut ? LIGHTS_OUT_DURATION : LIGHTS_IN_DURATION;
navButtons.animate()
.alpha(navButtonsAlpha)
.setDuration(duration)
.start();
lowLights.setOnTouchListener(mLightsOutListener);
if (lowLights.getVisibility() == View.GONE) {
lowLights.setAlpha(0f);
lowLights.setVisibility(View.VISIBLE);
}
lowLights.animate()
.alpha(lowLightsAlpha)
.setDuration(duration)
.setInterpolator(new AccelerateInterpolator(2.0f))
.setListener(lightsOut ? null : new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator _a) {
lowLights.setVisibility(View.GONE);
}
})
.start();
}
}
private final View.OnTouchListener mLightsOutListener = new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent ev) {
if (ev.getAction() == MotionEvent.ACTION_DOWN) {
// even though setting the systemUI visibility below will turn these views
// on, we need them to come up faster so that they can catch this motion
// event
applyLightsOut(false, false, false);
try {
mBarService.setSystemUiVisibility(0, View.SYSTEM_UI_FLAG_LOW_PROFILE);
} catch (android.os.RemoteException ex) {
}
}
return false;
}
};
}

View File

@ -16,8 +16,6 @@
package com.android.systemui.statusbar.phone;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.LayoutTransition;
import android.app.StatusBarManager;
import android.content.Context;
@ -25,11 +23,8 @@ import android.content.res.Resources;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.GradientDrawable;
import android.graphics.drawable.GradientDrawable.Orientation;
import android.os.Handler;
import android.os.Message;
import android.os.ServiceManager;
import android.util.AttributeSet;
import android.util.Log;
import android.view.Display;
@ -38,16 +33,13 @@ import android.view.Surface;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.view.animation.AccelerateInterpolator;
import android.widget.ImageView;
import android.widget.LinearLayout;
import com.android.internal.statusbar.IStatusBarService;
import com.android.systemui.R;
import com.android.systemui.statusbar.BaseStatusBar;
import com.android.systemui.statusbar.DelegateViewHelper;
import com.android.systemui.statusbar.policy.DeadZone;
import com.android.systemui.statusbar.policy.KeyButtonView;
import java.io.FileDescriptor;
import java.io.PrintWriter;
@ -59,11 +51,8 @@ public class NavigationBarView extends LinearLayout {
final static boolean NAVBAR_ALWAYS_AT_RIGHT = true;
// slippery nav bar when everything is disabled, e.g. during setup
final static boolean SLIPPERY_WHEN_DISABLED= true;
final static boolean SLIPPERY_WHEN_DISABLED = true;
final static boolean ANIMATE_HIDE_TRANSITION = false; // turned off because it introduces unsightly delay when videos goes to full screen
protected IStatusBarService mBarService;
final Display mDisplay;
View mCurrentView = null;
View[] mRotatedViews = new View[4];
@ -72,7 +61,7 @@ public class NavigationBarView extends LinearLayout {
boolean mVertical;
boolean mScreenOn;
boolean mHidden, mLowProfile, mShowMenu;
boolean mShowMenu;
int mDisabledFlags = 0;
int mNavigationIconHints = 0;
@ -111,62 +100,11 @@ public class NavigationBarView extends LinearLayout {
}
}
private final class NavigationBarTransitions extends BarTransitions {
private static final boolean ENABLE_GRADIENT = false; // until we can smooth transition
private final Drawable mTransparentBottom;
private final Drawable mTransparentRight;
private final int mTransparentColor;
public NavigationBarTransitions(Context context) {
super(context, NavigationBarView.this);
final Resources res = mContext.getResources();
final int[] gradientColors = new int[] {
res.getColor(R.color.navigation_bar_background_transparent_start),
res.getColor(R.color.navigation_bar_background_transparent_end)
};
mTransparentBottom = new GradientDrawable(Orientation.BOTTOM_TOP, gradientColors);
mTransparentRight = new GradientDrawable(Orientation.RIGHT_LEFT, gradientColors);
mTransparentColor = res.getColor(R.color.status_bar_background_transparent);
}
public void setVertical(boolean isVertical) {
if (!ENABLE_GRADIENT) return;
mTransparent = isVertical ? mTransparentRight : mTransparentBottom;
}
@Override
protected Integer getBackgroundColor(int mode) {
if (!ENABLE_GRADIENT && mode == MODE_TRANSPARENT) return mTransparentColor;
return super.getBackgroundColor(mode);
}
@Override
protected void onTransition(int oldMode, int newMode, boolean animate) {
super.onTransition(oldMode, newMode, animate);
final float alpha = newMode == MODE_OPAQUE ? KeyButtonView.DEFAULT_QUIESCENT_ALPHA : 1f;
setKeyButtonViewQuiescentAlpha(getBackButton(), alpha);
setKeyButtonViewQuiescentAlpha(getHomeButton(), alpha);
setKeyButtonViewQuiescentAlpha(getRecentsButton(), alpha);
setKeyButtonViewQuiescentAlpha(getMenuButton(), alpha);
}
private void setKeyButtonViewQuiescentAlpha(View button, float alpha) {
if (button instanceof KeyButtonView) {
((KeyButtonView) button).setQuiescentAlpha(alpha);
}
}
}
public NavigationBarView(Context context, AttributeSet attrs) {
super(context, attrs);
mHidden = false;
mDisplay = ((WindowManager)context.getSystemService(
Context.WINDOW_SERVICE)).getDefaultDisplay();
mBarService = IStatusBarService.Stub.asInterface(
ServiceManager.getService(Context.STATUS_BAR_SERVICE));
final Resources res = mContext.getResources();
mBarSize = res.getDimensionPixelSize(R.dimen.navigation_bar_size);
@ -176,7 +114,7 @@ public class NavigationBarView extends LinearLayout {
getIcons(res);
mBarTransitions = new NavigationBarTransitions(context);
mBarTransitions = new NavigationBarTransitions(this);
}
public BarTransitions getBarTransitions() {
@ -210,6 +148,10 @@ public class NavigationBarView extends LinearLayout {
private H mHandler = new H();
public View getCurrentView() {
return mCurrentView;
}
public View getRecentsButton() {
return mCurrentView.findViewById(R.id.recent_apps);
}
@ -252,24 +194,6 @@ public class NavigationBarView extends LinearLayout {
setDisabledFlags(mDisabledFlags, true);
}
View.OnTouchListener mLightsOutListener = new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent ev) {
if (ev.getAction() == MotionEvent.ACTION_DOWN) {
// even though setting the systemUI visibility below will turn these views
// on, we need them to come up faster so that they can catch this motion
// event
setLowProfile(false, false, false);
try {
mBarService.setSystemUiVisibility(0, View.SYSTEM_UI_FLAG_LOW_PROFILE);
} catch (android.os.RemoteException ex) {
}
}
return false;
}
};
public void setNavigationIconHints(int hints) {
setNavigationIconHints(hints, false);
}
@ -366,65 +290,6 @@ public class NavigationBarView extends LinearLayout {
getMenuButton().setVisibility(mShowMenu ? View.VISIBLE : View.INVISIBLE);
}
public void setLowProfile(final boolean lightsOut) {
setLowProfile(lightsOut, true, false);
}
public void setLowProfile(final boolean lightsOut, final boolean animate, final boolean force) {
if (!force && lightsOut == mLowProfile) return;
mLowProfile = lightsOut;
if (DEBUG) Log.d(TAG, "setting lights " + (lightsOut?"out":"on"));
final View navButtons = mCurrentView.findViewById(R.id.nav_buttons);
final View lowLights = mCurrentView.findViewById(R.id.lights_out);
// ok, everyone, stop it right there
navButtons.animate().cancel();
lowLights.animate().cancel();
if (!animate) {
navButtons.setAlpha(lightsOut ? 0f : 1f);
lowLights.setAlpha(lightsOut ? 1f : 0f);
lowLights.setVisibility(lightsOut ? View.VISIBLE : View.GONE);
} else {
navButtons.animate()
.alpha(lightsOut ? 0f : 1f)
.setDuration(lightsOut ? 750 : 250)
.start();
lowLights.setOnTouchListener(mLightsOutListener);
if (lowLights.getVisibility() == View.GONE) {
lowLights.setAlpha(0f);
lowLights.setVisibility(View.VISIBLE);
}
lowLights.animate()
.alpha(lightsOut ? 1f : 0f)
.setDuration(lightsOut ? 750 : 250)
.setInterpolator(new AccelerateInterpolator(2.0f))
.setListener(lightsOut ? null : new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator _a) {
lowLights.setVisibility(View.GONE);
}
})
.start();
}
}
public void setHidden(final boolean hide) {
if (hide == mHidden) return;
mHidden = hide;
Log.d(TAG,
(hide ? "HIDING" : "SHOWING") + " navigation bar");
// bring up the lights no matter what
setLowProfile(false);
}
@Override
public void onFinishInflate() {
mRotatedViews[Surface.ROTATION_0] =
@ -454,7 +319,7 @@ public class NavigationBarView extends LinearLayout {
mDeadZone = (DeadZone) mCurrentView.findViewById(R.id.deadzone);
// force the low profile & disabled states into compliance
setLowProfile(mLowProfile, false, true /* force */);
mBarTransitions.reapplyMode();
setDisabledFlags(mDisabledFlags, true /* force */);
setMenuVisibility(mShowMenu, true /* force */);
@ -562,8 +427,6 @@ public class NavigationBarView extends LinearLayout {
pw.println(String.format(" disabled=0x%08x vertical=%s hidden=%s low=%s menu=%s",
mDisabledFlags,
mVertical ? "true" : "false",
mHidden ? "true" : "false",
mLowProfile ? "true" : "false",
mShowMenu ? "true" : "false"));
final View back = getBackButton();

View File

@ -17,15 +17,16 @@
package com.android.systemui.statusbar.phone;
import static android.app.StatusBarManager.NAVIGATION_HINT_BACK_ALT;
import static android.app.StatusBarManager.WINDOW_STATE_HIDDEN;
import static android.app.StatusBarManager.WINDOW_STATE_SHOWING;
import static android.app.StatusBarManager.windowStateToString;
import static com.android.systemui.statusbar.phone.BarTransitions.MODE_OPAQUE;
import static com.android.systemui.statusbar.phone.BarTransitions.MODE_SEMI_TRANSPARENT;
import static com.android.systemui.statusbar.phone.BarTransitions.MODE_TRANSPARENT;
import static com.android.systemui.statusbar.phone.BarTransitions.MODE_LIGHTS_OUT;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.animation.TimeInterpolator;
import android.app.ActivityManager;
@ -251,9 +252,6 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode {
int[] mAbsPos = new int[2];
Runnable mPostCollapseCleanup = null;
private Animator mLightsOutAnimation;
private Animator mLightsOnAnimation;
// for disabling the status bar
int mDisabled = 0;
@ -1808,11 +1806,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode {
}
}
if (mNavigationBarView != null) {
mNavigationBarView.setLowProfile(lightsOut);
}
setStatusBarLowProfile(lightsOut);
setAreThereNotifications();
}
// update status bar mode
@ -1872,6 +1866,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode {
private int barMode(int vis, int transientFlag, int transparentFlag) {
return (vis & transientFlag) != 0 ? MODE_SEMI_TRANSPARENT
: (vis & transparentFlag) != 0 ? MODE_TRANSPARENT
: (vis & View.SYSTEM_UI_FLAG_LOW_PROFILE) != 0 ? MODE_LIGHTS_OUT
: MODE_OPAQUE;
}
@ -1888,7 +1883,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode {
private void checkBarMode(int mode, int windowState, BarTransitions transitions) {
final boolean imeVisible = (mNavigationIconHints & NAVIGATION_HINT_BACK_ALT) != 0;
final int finalMode = imeVisible ? MODE_OPAQUE : mode;
final boolean animate = windowState == WINDOW_STATE_SHOWING;
final boolean animate = windowState != WINDOW_STATE_HIDDEN;
transitions.transitionTo(finalMode, animate);
}
@ -1948,47 +1943,6 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode {
mHandler.postDelayed(mAutohide, 350); // longer than app gesture -> flag clear
}
private void setStatusBarLowProfile(boolean lightsOut) {
if (mLightsOutAnimation == null) {
final View notifications = mStatusBarView.findViewById(R.id.notification_icon_area);
final View systemIcons = mStatusBarView.findViewById(R.id.statusIcons);
final View signal = mStatusBarView.findViewById(R.id.signal_cluster);
final View battery = mStatusBarView.findViewById(R.id.battery);
final View clock = mStatusBarView.findViewById(R.id.clock);
final AnimatorSet lightsOutAnim = new AnimatorSet();
lightsOutAnim.playTogether(
ObjectAnimator.ofFloat(notifications, View.ALPHA, 0),
ObjectAnimator.ofFloat(systemIcons, View.ALPHA, 0),
ObjectAnimator.ofFloat(signal, View.ALPHA, 0),
ObjectAnimator.ofFloat(battery, View.ALPHA, 0.5f),
ObjectAnimator.ofFloat(clock, View.ALPHA, 0.5f)
);
lightsOutAnim.setDuration(750);
final AnimatorSet lightsOnAnim = new AnimatorSet();
lightsOnAnim.playTogether(
ObjectAnimator.ofFloat(notifications, View.ALPHA, 1),
ObjectAnimator.ofFloat(systemIcons, View.ALPHA, 1),
ObjectAnimator.ofFloat(signal, View.ALPHA, 1),
ObjectAnimator.ofFloat(battery, View.ALPHA, 1),
ObjectAnimator.ofFloat(clock, View.ALPHA, 1)
);
lightsOnAnim.setDuration(250);
mLightsOutAnimation = lightsOutAnim;
mLightsOnAnimation = lightsOnAnim;
}
mLightsOutAnimation.cancel();
mLightsOnAnimation.cancel();
final Animator a = lightsOut ? mLightsOutAnimation : mLightsOnAnimation;
a.start();
setAreThereNotifications();
}
private boolean areLightsOn() {
return 0 == (mSystemUiVisibility & View.SYSTEM_UI_FLAG_LOW_PROFILE);
}

View File

@ -0,0 +1,117 @@
/*
* Copyright (C) 2013 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.statusbar.phone;
import android.animation.Animator;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.content.res.Resources;
import android.util.Log;
import android.view.View;
import com.android.systemui.R;
public final class PhoneStatusBarTransitions extends BarTransitions {
private static final float ALPHA_WHEN_TRANSPARENT = 1;
private static final float ALPHA_WHEN_LIGHTS_OUT_BATTERY_CLOCK = 0.5f;
private static final float ALPHA_WHEN_LIGHTS_OUT_NON_BATTERY_CLOCK = 0;
private final PhoneStatusBarView mView;
private final int mTransparent;
private final float mAlphaWhenOpaque;
private View mLeftSide, mStatusIcons, mSignalCluster, mBattery, mClock;
private Animator mCurrentAnimation;
public PhoneStatusBarTransitions(PhoneStatusBarView view) {
super(view);
mView = view;
final Resources res = mView.getContext().getResources();
mTransparent = res.getColor(R.color.status_bar_background_transparent);
mAlphaWhenOpaque = res.getFraction(R.dimen.status_bar_icon_drawing_alpha, 1, 1);
}
public void init() {
mLeftSide = mView.findViewById(R.id.notification_icon_area);
mStatusIcons = mView.findViewById(R.id.statusIcons);
mSignalCluster = mView.findViewById(R.id.signal_cluster);
mBattery = mView.findViewById(R.id.battery);
mClock = mView.findViewById(R.id.clock);
applyMode(getMode(), false /*animate*/);
}
@Override
protected Integer getBackgroundColor(int mode) {
if (mode == MODE_TRANSPARENT) return mTransparent;
return super.getBackgroundColor(mode);
}
public ObjectAnimator animateTransitionTo(View v, float toAlpha) {
return ObjectAnimator.ofFloat(v, "alpha", v.getAlpha(), toAlpha);
}
private float getNonBatteryClockAlphaFor(int mode) {
return mode == MODE_LIGHTS_OUT ? ALPHA_WHEN_LIGHTS_OUT_NON_BATTERY_CLOCK
: isTransparent(mode) ? ALPHA_WHEN_TRANSPARENT
: mAlphaWhenOpaque;
}
private float getBatteryClockAlpha(int mode) {
return mode == MODE_LIGHTS_OUT ? ALPHA_WHEN_LIGHTS_OUT_BATTERY_CLOCK
: getNonBatteryClockAlphaFor(mode);
}
private boolean isTransparent(int mode) {
return mode == MODE_SEMI_TRANSPARENT || mode == MODE_TRANSPARENT;
}
@Override
protected void onTransition(int oldMode, int newMode, boolean animate) {
super.onTransition(oldMode, newMode, animate);
applyMode(newMode, animate);
}
private void applyMode(int mode, boolean animate) {
if (mLeftSide == null) return; // pre-init
float newAlpha = getNonBatteryClockAlphaFor(mode);
float newAlphaBC = getBatteryClockAlpha(mode);
if (mCurrentAnimation != null) {
mCurrentAnimation.cancel();
}
if (animate) {
AnimatorSet anims = new AnimatorSet();
anims.playTogether(
animateTransitionTo(mLeftSide, newAlpha),
animateTransitionTo(mStatusIcons, newAlpha),
animateTransitionTo(mSignalCluster, newAlpha),
animateTransitionTo(mBattery, newAlphaBC),
animateTransitionTo(mClock, newAlphaBC)
);
if (mode == MODE_LIGHTS_OUT) {
anims.setDuration(LIGHTS_OUT_DURATION);
}
anims.start();
mCurrentAnimation = anims;
} else {
mLeftSide.setAlpha(newAlpha);
mStatusIcons.setAlpha(newAlpha);
mSignalCluster.setAlpha(newAlpha);
mBattery.setAlpha(newAlphaBC);
mClock.setAlpha(newAlphaBC);
}
}
}

View File

@ -16,8 +16,6 @@
package com.android.systemui.statusbar.phone;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.app.ActivityManager;
import android.content.Context;
import android.content.res.Resources;
@ -47,73 +45,7 @@ public class PhoneStatusBarView extends PanelBar {
PanelView mLastFullyOpenedPanel = null;
PanelView mNotificationPanel, mSettingsPanel;
private boolean mShouldFade;
private final StatusBarTransitions mBarTransitions;
private final class StatusBarTransitions extends BarTransitions {
private final int mTransparent;
private final float mAlphaWhenOpaque;
private final float mAlphaWhenTransparent = 1;
private View mLeftSide, mStatusIcons, mSignalCluster, mClock;
public StatusBarTransitions(Context context) {
super(context, PhoneStatusBarView.this);
final Resources res = context.getResources();
mTransparent = res.getColor(R.color.status_bar_background_transparent);
mAlphaWhenOpaque = res.getFraction(R.dimen.status_bar_icon_drawing_alpha, 1, 1);
}
public void init() {
mLeftSide = findViewById(R.id.notification_icon_area);
mStatusIcons = findViewById(R.id.statusIcons);
mSignalCluster = findViewById(R.id.signal_battery_cluster);
mClock = findViewById(R.id.clock);
applyMode(getMode(), false /*animate*/);
}
@Override
protected Integer getBackgroundColor(int mode) {
if (mode == MODE_TRANSPARENT) return mTransparent;
return super.getBackgroundColor(mode);
}
public ObjectAnimator animateTransitionTo(View v, float toAlpha) {
return ObjectAnimator.ofFloat(v, "alpha", v.getAlpha(), toAlpha);
}
public float getAlphaFor(int mode) {
return isTransparent(mode) ? mAlphaWhenTransparent : mAlphaWhenOpaque;
}
private boolean isTransparent(int mode) {
return mode == MODE_SEMI_TRANSPARENT || mode == MODE_TRANSPARENT;
}
@Override
protected void onTransition(int oldMode, int newMode, boolean animate) {
super.onTransition(oldMode, newMode, animate);
applyMode(newMode, animate);
}
private void applyMode(int mode, boolean animate) {
if (mLeftSide == null) return; // pre-init
float newAlpha = getAlphaFor(mode);
if (animate) {
AnimatorSet anims = new AnimatorSet();
anims.playTogether(
animateTransitionTo(mLeftSide, newAlpha),
animateTransitionTo(mStatusIcons, newAlpha),
animateTransitionTo(mSignalCluster, newAlpha),
animateTransitionTo(mClock, newAlpha)
);
anims.start();
} else {
mLeftSide.setAlpha(newAlpha);
mStatusIcons.setAlpha(newAlpha);
mSignalCluster.setAlpha(newAlpha);
mClock.setAlpha(newAlpha);
}
}
}
private final PhoneStatusBarTransitions mBarTransitions;
public PhoneStatusBarView(Context context, AttributeSet attrs) {
super(context, attrs);
@ -127,7 +59,7 @@ public class PhoneStatusBarView extends PanelBar {
mSettingsPanelDragzoneFrac = 0f;
}
mFullWidthNotifications = mSettingsPanelDragzoneFrac <= 0f;
mBarTransitions = new StatusBarTransitions(context);
mBarTransitions = new PhoneStatusBarTransitions(this);
}
public BarTransitions getBarTransitions() {

View File

@ -17,8 +17,6 @@
package com.android.systemui.statusbar.policy;
import android.animation.Animator;
import android.animation.Animator.AnimatorListener;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.content.Context;
@ -60,6 +58,7 @@ public class KeyButtonView extends ImageView {
boolean mSupportsLongpress = true;
RectF mRect = new RectF(0f,0f,0f,0f);
AnimatorSet mPressedAnim;
Animator mAnimateToQuiescent = new ObjectAnimator();
Runnable mCheckLongPress = new Runnable() {
public void run() {
@ -76,15 +75,6 @@ public class KeyButtonView extends ImageView {
}
};
private final AnimatorListener mRecoverToQuiescentListener = new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
if (mQuiescentAlpha != mDrawingAlpha) {
animateToQuiescent().setDuration(200).start();
}
}
};
public KeyButtonView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
@ -133,16 +123,26 @@ public class KeyButtonView extends ImageView {
super.onDraw(canvas);
}
public void setQuiescentAlpha(float alpha) {
public void setQuiescentAlpha(float alpha, boolean animate) {
mAnimateToQuiescent.cancel();
alpha = Math.min(Math.max(alpha, 0), 1);
if (alpha == mQuiescentAlpha) return;
mQuiescentAlpha = alpha;
if (DEBUG) Log.d(TAG, "New quiescent alpha = " + mQuiescentAlpha);
if (mGlowBG != null) {
setDrawingAlpha(mQuiescentAlpha);
if (animate) {
mAnimateToQuiescent = animateToQuiescent();
mAnimateToQuiescent.start();
} else {
setDrawingAlpha(mQuiescentAlpha);
}
}
}
private ObjectAnimator animateToQuiescent() {
return ObjectAnimator.ofFloat(this, "drawingAlpha", mQuiescentAlpha);
}
public float getDrawingAlpha() {
if (mGlowBG == null) return 0;
return mDrawingAlpha;
@ -197,12 +197,6 @@ public class KeyButtonView extends ImageView {
}
}
private ObjectAnimator animateToQuiescent() {
ObjectAnimator anim = ObjectAnimator.ofFloat(this, "drawingAlpha", mQuiescentAlpha);
anim.addListener(mRecoverToQuiescentListener); // mQuiescentAlpha may change mid-animation
return anim;
}
public void setPressed(boolean pressed) {
if (mGlowBG != null) {
if (pressed != isPressed()) {
@ -222,10 +216,12 @@ public class KeyButtonView extends ImageView {
);
as.setDuration(50);
} else {
mAnimateToQuiescent.cancel();
mAnimateToQuiescent = animateToQuiescent();
as.playTogether(
ObjectAnimator.ofFloat(this, "glowAlpha", 0f),
ObjectAnimator.ofFloat(this, "glowScale", 1f),
animateToQuiescent()
mAnimateToQuiescent
);
as.setDuration(500);
}

View File

@ -33,7 +33,7 @@ import java.io.PrintWriter;
* Controls state/behavior specific to a system bar window.
*/
public class BarController {
private static final boolean DEBUG = true;
private static final boolean DEBUG = false;
private static final int TRANSIENT_BAR_NONE = 0;
private static final int TRANSIENT_BAR_SHOWING = 1;
@ -106,24 +106,32 @@ public class BarController {
mPendingShow = true;
return false;
}
final boolean oldVis = mWin.isVisibleLw();
final boolean oldAnim = mWin.isAnimatingLw();
final boolean rt = show ? mWin.showLw(true) : mWin.hideLw(true);
final int state = computeState(oldVis, oldAnim, mWin.isVisibleLw(), mWin.isAnimatingLw());
if (state > -1 && mWin.hasDrawnLw()) {
updateState(state);
final boolean wasVis = mWin.isVisibleLw();
final boolean wasAnim = mWin.isAnimatingLw();
final boolean change = show ? mWin.showLw(true) : mWin.hideLw(true);
final int state = computeStateLw(wasVis, wasAnim, mWin, change);
updateStateLw(state);
return change;
}
private int computeStateLw(boolean wasVis, boolean wasAnim, WindowState win, boolean change) {
if (win.hasDrawnLw()) {
final boolean vis = win.isVisibleLw();
final boolean anim = win.isAnimatingLw();
if (mState == StatusBarManager.WINDOW_STATE_HIDING && !change && !vis) {
return StatusBarManager.WINDOW_STATE_HIDDEN;
} else if (change) {
if (wasVis && vis && !wasAnim && anim) {
return StatusBarManager.WINDOW_STATE_HIDING;
} else {
return StatusBarManager.WINDOW_STATE_SHOWING;
}
}
}
return rt;
return mState;
}
private int computeState(boolean oldVis, boolean oldAnim, boolean newVis, boolean newAnim) {
return (!newVis && !newAnim) ? StatusBarManager.WINDOW_STATE_HIDDEN
: (!oldVis && newVis && newAnim) ? StatusBarManager.WINDOW_STATE_SHOWING
: (oldVis && newVis && !oldAnim && newAnim) ? StatusBarManager.WINDOW_STATE_HIDING
: -1;
}
private void updateState(final int state) {
private void updateStateLw(final int state) {
if (state != mState) {
mState = state;
if (DEBUG) Slog.d(mTag, "mState: " + StatusBarManager.windowStateToString(state));
@ -148,7 +156,7 @@ public class BarController {
public boolean checkHiddenLw() {
if (mWin != null && mWin.hasDrawnLw()) {
if (!mWin.isVisibleLw() && !mWin.isAnimatingLw()) {
updateState(StatusBarManager.WINDOW_STATE_HIDDEN);
updateStateLw(StatusBarManager.WINDOW_STATE_HIDDEN);
}
if (mTransientBarState == TRANSIENT_BAR_HIDING && !mWin.isVisibleLw()) {
// Finished animating out, clean up and reset style