Merge "Promote lights-out to a bar transition mode." into klp-dev

This commit is contained in:
John Spurlock
2013-09-14 21:31:09 +00:00
committed by Android (Google) Code Review
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;
import android.animation.ValueAnimator.AnimatorUpdateListener; import android.animation.ValueAnimator.AnimatorUpdateListener;
import android.app.ActivityManager; import android.app.ActivityManager;
import android.content.Context;
import android.content.res.Resources; import android.content.res.Resources;
import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
@ -35,6 +34,10 @@ public class BarTransitions {
public static final int MODE_OPAQUE = 0; public static final int MODE_OPAQUE = 0;
public static final int MODE_SEMI_TRANSPARENT = 1; public static final int MODE_SEMI_TRANSPARENT = 1;
public static final int MODE_TRANSPARENT = 2; 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; private final String mTag;
protected final View mTarget; 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(); mTag = "BarTransitions." + target.getClass().getSimpleName();
mTarget = target; mTarget = target;
final Resources res = context.getResources(); final Resources res = target.getContext().getResources();
mOpaque = res.getColor(R.drawable.status_bar_background); mOpaque = res.getColor(R.drawable.status_bar_background);
mSemiTransparent = res.getColor(R.color.status_bar_background_semi_transparent); mSemiTransparent = res.getColor(R.color.status_bar_background_semi_transparent);
} }
@ -76,6 +79,7 @@ public class BarTransitions {
protected Integer getBackgroundColor(int mode) { protected Integer getBackgroundColor(int mode) {
if (mode == MODE_SEMI_TRANSPARENT) return mSemiTransparent; if (mode == MODE_SEMI_TRANSPARENT) return mSemiTransparent;
if (mode == MODE_OPAQUE) return mOpaque; if (mode == MODE_OPAQUE) return mOpaque;
if (mode == MODE_LIGHTS_OUT) return mOpaque;
return null; return null;
} }
@ -113,6 +117,7 @@ public class BarTransitions {
if (mode == MODE_OPAQUE) return "MODE_OPAQUE"; if (mode == MODE_OPAQUE) return "MODE_OPAQUE";
if (mode == MODE_SEMI_TRANSPARENT) return "MODE_SEMI_TRANSPARENT"; if (mode == MODE_SEMI_TRANSPARENT) return "MODE_SEMI_TRANSPARENT";
if (mode == MODE_TRANSPARENT) return "MODE_TRANSPARENT"; if (mode == MODE_TRANSPARENT) return "MODE_TRANSPARENT";
if (mode == MODE_LIGHTS_OUT) return "MODE_LIGHTS_OUT";
throw new IllegalArgumentException("Unknown mode " + mode); 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; package com.android.systemui.statusbar.phone;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.LayoutTransition; import android.animation.LayoutTransition;
import android.app.StatusBarManager; import android.app.StatusBarManager;
import android.content.Context; import android.content.Context;
@ -25,11 +23,8 @@ import android.content.res.Resources;
import android.graphics.Point; import android.graphics.Point;
import android.graphics.Rect; import android.graphics.Rect;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.graphics.drawable.GradientDrawable;
import android.graphics.drawable.GradientDrawable.Orientation;
import android.os.Handler; import android.os.Handler;
import android.os.Message; import android.os.Message;
import android.os.ServiceManager;
import android.util.AttributeSet; import android.util.AttributeSet;
import android.util.Log; import android.util.Log;
import android.view.Display; import android.view.Display;
@ -38,16 +33,13 @@ import android.view.Surface;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.view.WindowManager; import android.view.WindowManager;
import android.view.animation.AccelerateInterpolator;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.LinearLayout; import android.widget.LinearLayout;
import com.android.internal.statusbar.IStatusBarService;
import com.android.systemui.R; import com.android.systemui.R;
import com.android.systemui.statusbar.BaseStatusBar; import com.android.systemui.statusbar.BaseStatusBar;
import com.android.systemui.statusbar.DelegateViewHelper; import com.android.systemui.statusbar.DelegateViewHelper;
import com.android.systemui.statusbar.policy.DeadZone; import com.android.systemui.statusbar.policy.DeadZone;
import com.android.systemui.statusbar.policy.KeyButtonView;
import java.io.FileDescriptor; import java.io.FileDescriptor;
import java.io.PrintWriter; import java.io.PrintWriter;
@ -61,9 +53,6 @@ public class NavigationBarView extends LinearLayout {
// slippery nav bar when everything is disabled, e.g. during setup // 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; final Display mDisplay;
View mCurrentView = null; View mCurrentView = null;
View[] mRotatedViews = new View[4]; View[] mRotatedViews = new View[4];
@ -72,7 +61,7 @@ public class NavigationBarView extends LinearLayout {
boolean mVertical; boolean mVertical;
boolean mScreenOn; boolean mScreenOn;
boolean mHidden, mLowProfile, mShowMenu; boolean mShowMenu;
int mDisabledFlags = 0; int mDisabledFlags = 0;
int mNavigationIconHints = 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) { public NavigationBarView(Context context, AttributeSet attrs) {
super(context, attrs); super(context, attrs);
mHidden = false;
mDisplay = ((WindowManager)context.getSystemService( mDisplay = ((WindowManager)context.getSystemService(
Context.WINDOW_SERVICE)).getDefaultDisplay(); Context.WINDOW_SERVICE)).getDefaultDisplay();
mBarService = IStatusBarService.Stub.asInterface(
ServiceManager.getService(Context.STATUS_BAR_SERVICE));
final Resources res = mContext.getResources(); final Resources res = mContext.getResources();
mBarSize = res.getDimensionPixelSize(R.dimen.navigation_bar_size); mBarSize = res.getDimensionPixelSize(R.dimen.navigation_bar_size);
@ -176,7 +114,7 @@ public class NavigationBarView extends LinearLayout {
getIcons(res); getIcons(res);
mBarTransitions = new NavigationBarTransitions(context); mBarTransitions = new NavigationBarTransitions(this);
} }
public BarTransitions getBarTransitions() { public BarTransitions getBarTransitions() {
@ -210,6 +148,10 @@ public class NavigationBarView extends LinearLayout {
private H mHandler = new H(); private H mHandler = new H();
public View getCurrentView() {
return mCurrentView;
}
public View getRecentsButton() { public View getRecentsButton() {
return mCurrentView.findViewById(R.id.recent_apps); return mCurrentView.findViewById(R.id.recent_apps);
} }
@ -252,24 +194,6 @@ public class NavigationBarView extends LinearLayout {
setDisabledFlags(mDisabledFlags, true); 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) { public void setNavigationIconHints(int hints) {
setNavigationIconHints(hints, false); setNavigationIconHints(hints, false);
} }
@ -366,65 +290,6 @@ public class NavigationBarView extends LinearLayout {
getMenuButton().setVisibility(mShowMenu ? View.VISIBLE : View.INVISIBLE); 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 @Override
public void onFinishInflate() { public void onFinishInflate() {
mRotatedViews[Surface.ROTATION_0] = mRotatedViews[Surface.ROTATION_0] =
@ -454,7 +319,7 @@ public class NavigationBarView extends LinearLayout {
mDeadZone = (DeadZone) mCurrentView.findViewById(R.id.deadzone); mDeadZone = (DeadZone) mCurrentView.findViewById(R.id.deadzone);
// force the low profile & disabled states into compliance // force the low profile & disabled states into compliance
setLowProfile(mLowProfile, false, true /* force */); mBarTransitions.reapplyMode();
setDisabledFlags(mDisabledFlags, true /* force */); setDisabledFlags(mDisabledFlags, true /* force */);
setMenuVisibility(mShowMenu, 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", pw.println(String.format(" disabled=0x%08x vertical=%s hidden=%s low=%s menu=%s",
mDisabledFlags, mDisabledFlags,
mVertical ? "true" : "false", mVertical ? "true" : "false",
mHidden ? "true" : "false",
mLowProfile ? "true" : "false",
mShowMenu ? "true" : "false")); mShowMenu ? "true" : "false"));
final View back = getBackButton(); final View back = getBackButton();

View File

@ -17,15 +17,16 @@
package com.android.systemui.statusbar.phone; package com.android.systemui.statusbar.phone;
import static android.app.StatusBarManager.NAVIGATION_HINT_BACK_ALT; 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.WINDOW_STATE_SHOWING;
import static android.app.StatusBarManager.windowStateToString; 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_OPAQUE;
import static com.android.systemui.statusbar.phone.BarTransitions.MODE_SEMI_TRANSPARENT; 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_TRANSPARENT;
import static com.android.systemui.statusbar.phone.BarTransitions.MODE_LIGHTS_OUT;
import android.animation.Animator; import android.animation.Animator;
import android.animation.AnimatorListenerAdapter; import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator; import android.animation.ObjectAnimator;
import android.animation.TimeInterpolator; import android.animation.TimeInterpolator;
import android.app.ActivityManager; import android.app.ActivityManager;
@ -251,9 +252,6 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode {
int[] mAbsPos = new int[2]; int[] mAbsPos = new int[2];
Runnable mPostCollapseCleanup = null; Runnable mPostCollapseCleanup = null;
private Animator mLightsOutAnimation;
private Animator mLightsOnAnimation;
// for disabling the status bar // for disabling the status bar
int mDisabled = 0; int mDisabled = 0;
@ -1808,11 +1806,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode {
} }
} }
if (mNavigationBarView != null) { setAreThereNotifications();
mNavigationBarView.setLowProfile(lightsOut);
}
setStatusBarLowProfile(lightsOut);
} }
// update status bar mode // update status bar mode
@ -1872,6 +1866,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode {
private int barMode(int vis, int transientFlag, int transparentFlag) { private int barMode(int vis, int transientFlag, int transparentFlag) {
return (vis & transientFlag) != 0 ? MODE_SEMI_TRANSPARENT return (vis & transientFlag) != 0 ? MODE_SEMI_TRANSPARENT
: (vis & transparentFlag) != 0 ? MODE_TRANSPARENT : (vis & transparentFlag) != 0 ? MODE_TRANSPARENT
: (vis & View.SYSTEM_UI_FLAG_LOW_PROFILE) != 0 ? MODE_LIGHTS_OUT
: MODE_OPAQUE; : MODE_OPAQUE;
} }
@ -1888,7 +1883,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode {
private void checkBarMode(int mode, int windowState, BarTransitions transitions) { private void checkBarMode(int mode, int windowState, BarTransitions transitions) {
final boolean imeVisible = (mNavigationIconHints & NAVIGATION_HINT_BACK_ALT) != 0; final boolean imeVisible = (mNavigationIconHints & NAVIGATION_HINT_BACK_ALT) != 0;
final int finalMode = imeVisible ? MODE_OPAQUE : mode; 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); 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 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() { private boolean areLightsOn() {
return 0 == (mSystemUiVisibility & View.SYSTEM_UI_FLAG_LOW_PROFILE); 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; package com.android.systemui.statusbar.phone;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.app.ActivityManager; import android.app.ActivityManager;
import android.content.Context; import android.content.Context;
import android.content.res.Resources; import android.content.res.Resources;
@ -47,73 +45,7 @@ public class PhoneStatusBarView extends PanelBar {
PanelView mLastFullyOpenedPanel = null; PanelView mLastFullyOpenedPanel = null;
PanelView mNotificationPanel, mSettingsPanel; PanelView mNotificationPanel, mSettingsPanel;
private boolean mShouldFade; private boolean mShouldFade;
private final StatusBarTransitions mBarTransitions; private final PhoneStatusBarTransitions 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);
}
}
}
public PhoneStatusBarView(Context context, AttributeSet attrs) { public PhoneStatusBarView(Context context, AttributeSet attrs) {
super(context, attrs); super(context, attrs);
@ -127,7 +59,7 @@ public class PhoneStatusBarView extends PanelBar {
mSettingsPanelDragzoneFrac = 0f; mSettingsPanelDragzoneFrac = 0f;
} }
mFullWidthNotifications = mSettingsPanelDragzoneFrac <= 0f; mFullWidthNotifications = mSettingsPanelDragzoneFrac <= 0f;
mBarTransitions = new StatusBarTransitions(context); mBarTransitions = new PhoneStatusBarTransitions(this);
} }
public BarTransitions getBarTransitions() { public BarTransitions getBarTransitions() {

View File

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

View File

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