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:
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
};
|
||||
}
|
@ -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();
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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() {
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
Reference in New Issue
Block a user