am b77edbfd: Improve transparent bar transitions.

* commit 'b77edbfdab54531023c8bbea7d89b6cefc42096c':
  Improve transparent bar transitions.
This commit is contained in:
John Spurlock
2013-08-23 05:24:28 -07:00
committed by Android Git Automerger
8 changed files with 136 additions and 25 deletions

View File

@@ -114,7 +114,7 @@ public class AnimationSet extends Animation {
* Constructor to use when building an AnimationSet from code * Constructor to use when building an AnimationSet from code
* *
* @param shareInterpolator Pass true if all of the animations in this set * @param shareInterpolator Pass true if all of the animations in this set
* should use the interpolator assocciated with this AnimationSet. * should use the interpolator associated with this AnimationSet.
* Pass false if each animation should use its own interpolator. * Pass false if each animation should use its own interpolator.
*/ */
public AnimationSet(boolean shareInterpolator) { public AnimationSet(boolean shareInterpolator) {

View File

@@ -70,6 +70,7 @@ import com.android.systemui.R;
import com.android.systemui.RecentsComponent; import com.android.systemui.RecentsComponent;
import com.android.systemui.SearchPanelView; import com.android.systemui.SearchPanelView;
import com.android.systemui.SystemUI; import com.android.systemui.SystemUI;
import com.android.systemui.statusbar.phone.BarTransitions;
import com.android.systemui.statusbar.policy.NotificationRowLayout; import com.android.systemui.statusbar.policy.NotificationRowLayout;
import java.util.ArrayList; import java.util.ArrayList;
@@ -827,7 +828,7 @@ public abstract class BaseStatusBar extends SystemUI implements
// Construct the icon. // Construct the icon.
final StatusBarIconView iconView = new StatusBarIconView(mContext, final StatusBarIconView iconView = new StatusBarIconView(mContext,
notification.getPackageName() + "/0x" + Integer.toHexString(notification.getId()), notification.getPackageName() + "/0x" + Integer.toHexString(notification.getId()),
notification.getNotification()); notification.getNotification(), getStatusBarMode());
iconView.setScaleType(ImageView.ScaleType.CENTER_INSIDE); iconView.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
final StatusBarIcon ic = new StatusBarIcon(notification.getPackageName(), final StatusBarIcon ic = new StatusBarIcon(notification.getPackageName(),
@@ -850,6 +851,10 @@ public abstract class BaseStatusBar extends SystemUI implements
return entry; return entry;
} }
protected int getStatusBarMode() {
return BarTransitions.MODE_OPAQUE;
}
protected void addNotificationViews(NotificationData.Entry entry) { protected void addNotificationViews(NotificationData.Entry entry) {
// Add the expanded view and icon. // Add the expanded view and icon.
int pos = mNotificationData.add(entry); int pos = mNotificationData.add(entry);

View File

@@ -16,6 +16,11 @@
package com.android.systemui.statusbar; package com.android.systemui.statusbar;
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 android.animation.ObjectAnimator;
import android.app.Notification; import android.app.Notification;
import android.content.Context; import android.content.Context;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
@@ -48,10 +53,13 @@ public class StatusBarIconView extends AnimatedImageView {
private int mNumberY; private int mNumberY;
private String mNumberText; private String mNumberText;
private Notification mNotification; private Notification mNotification;
private final float mAlphaWhenOpaque;
private final float mAlphaWhenTransparent = 1;
public StatusBarIconView(Context context, String slot, Notification notification) { public StatusBarIconView(Context context, String slot, Notification notification, int mode) {
super(context); super(context);
final Resources res = context.getResources(); final Resources res = context.getResources();
mAlphaWhenOpaque = res.getFraction(R.dimen.status_bar_icon_drawing_alpha, 1, 1);
mSlot = slot; mSlot = slot;
mNumberPain = new Paint(); mNumberPain = new Paint();
mNumberPain.setTextAlign(Paint.Align.CENTER); mNumberPain.setTextAlign(Paint.Align.CENTER);
@@ -68,8 +76,7 @@ public class StatusBarIconView extends AnimatedImageView {
final float scale = (float)imageBounds / (float)outerBounds; final float scale = (float)imageBounds / (float)outerBounds;
setScaleX(scale); setScaleX(scale);
setScaleY(scale); setScaleY(scale);
final float alpha = res.getFraction(R.dimen.status_bar_icon_drawing_alpha, 1, 1); setAlpha(getAlphaFor(mode));
setAlpha(alpha);
} }
setScaleType(ImageView.ScaleType.CENTER); setScaleType(ImageView.ScaleType.CENTER);
@@ -78,13 +85,22 @@ public class StatusBarIconView extends AnimatedImageView {
public StatusBarIconView(Context context, AttributeSet attrs) { public StatusBarIconView(Context context, AttributeSet attrs) {
super(context, attrs); super(context, attrs);
final Resources res = context.getResources(); final Resources res = context.getResources();
mAlphaWhenOpaque = res.getFraction(R.dimen.status_bar_icon_drawing_alpha, 1, 1);
final int outerBounds = res.getDimensionPixelSize(R.dimen.status_bar_icon_size); final int outerBounds = res.getDimensionPixelSize(R.dimen.status_bar_icon_size);
final int imageBounds = res.getDimensionPixelSize(R.dimen.status_bar_icon_drawing_size); final int imageBounds = res.getDimensionPixelSize(R.dimen.status_bar_icon_drawing_size);
final float scale = (float)imageBounds / (float)outerBounds; final float scale = (float)imageBounds / (float)outerBounds;
setScaleX(scale); setScaleX(scale);
setScaleY(scale); setScaleY(scale);
final float alpha = res.getFraction(R.dimen.status_bar_icon_drawing_alpha, 1, 1); setAlpha(getAlphaFor(MODE_OPAQUE));
setAlpha(alpha); }
public ObjectAnimator animateTransitionTo(int mode) {
return ObjectAnimator.ofFloat(this, "alpha", getAlpha(), getAlphaFor(mode));
}
public float getAlphaFor(int mode) {
final boolean isTransparent = mode == MODE_SEMI_TRANSPARENT || mode == MODE_TRANSPARENT;
return isTransparent ? mAlphaWhenTransparent : mAlphaWhenOpaque;
} }
private static boolean streq(String a, String b) { private static boolean streq(String a, String b) {

View File

@@ -60,6 +60,10 @@ public class BarTransitions {
mSemiTransparent = res.getColor(R.color.status_bar_background_semi_transparent); mSemiTransparent = res.getColor(R.color.status_bar_background_semi_transparent);
} }
public int getMode() {
return mMode;
}
public void setTransparent(Drawable transparent) { public void setTransparent(Drawable transparent) {
mTransparent = transparent; mTransparent = transparent;
if (mMode == MODE_TRANSPARENT) { if (mMode == MODE_TRANSPARENT) {
@@ -80,16 +84,24 @@ public class BarTransitions {
onTransition(oldMode, mMode, animate); onTransition(oldMode, mMode, animate);
} }
protected Integer getBackgroundColor(int mode) {
if (mode == MODE_SEMI_TRANSPARENT) return mSemiTransparent;
if (mode == MODE_OPAQUE) return mOpaque;
return null;
}
protected void onTransition(int oldMode, int newMode, boolean animate) { protected void onTransition(int oldMode, int newMode, boolean animate) {
cancelBackgroundColorAnimation(); cancelBackgroundColorAnimation();
if (animate && oldMode == MODE_SEMI_TRANSPARENT && newMode == MODE_OPAQUE) { Integer oldColor = getBackgroundColor(oldMode);
startBackgroundColorAnimation(mSemiTransparent, mOpaque); Integer newColor = getBackgroundColor(newMode);
} else if (animate && oldMode == MODE_OPAQUE && newMode == MODE_SEMI_TRANSPARENT) { if (oldColor != null && newColor != null) {
startBackgroundColorAnimation(mOpaque, mSemiTransparent); if (animate) {
} else if (newMode == MODE_OPAQUE || newMode == MODE_SEMI_TRANSPARENT) { startBackgroundColorAnimation(oldColor, newColor);
mTarget.setBackgroundColor(newMode == MODE_OPAQUE ? mOpaque : mSemiTransparent); } else {
mTarget.setBackgroundColor(newColor);
}
} else { } else {
mTarget.setBackground(newMode == MODE_TRANSPARENT? mTransparent mTarget.setBackground(newMode == MODE_TRANSPARENT ? mTransparent
: newMode == MODE_SEMI_TRANSPARENT ? new ColorDrawable(mSemiTransparent) : newMode == MODE_SEMI_TRANSPARENT ? new ColorDrawable(mSemiTransparent)
: new ColorDrawable(mOpaque)); : new ColorDrawable(mOpaque));
} }

View File

@@ -843,7 +843,7 @@ public class PhoneStatusBar extends BaseStatusBar {
public void addIcon(String slot, int index, int viewIndex, StatusBarIcon icon) { public void addIcon(String slot, int index, int viewIndex, StatusBarIcon icon) {
if (SPEW) Log.d(TAG, "addIcon slot=" + slot + " index=" + index + " viewIndex=" + viewIndex if (SPEW) Log.d(TAG, "addIcon slot=" + slot + " index=" + index + " viewIndex=" + viewIndex
+ " icon=" + icon); + " icon=" + icon);
StatusBarIconView view = new StatusBarIconView(mContext, slot, null); StatusBarIconView view = new StatusBarIconView(mContext, slot, null, getStatusBarMode());
view.set(icon); view.set(icon);
mStatusIcons.addView(view, viewIndex, new LinearLayout.LayoutParams(mIconSize, mIconSize)); mStatusIcons.addView(view, viewIndex, new LinearLayout.LayoutParams(mIconSize, mIconSize));
} }
@@ -1921,6 +1921,11 @@ public class PhoneStatusBar extends BaseStatusBar {
} }
} }
@Override
protected int getStatusBarMode() {
return mStatusBarView.getBarTransitions().getMode();
}
private int updateBarMode(int oldVis, int newVis, BarTransitions transitions, private int updateBarMode(int oldVis, int newVis, BarTransitions transitions,
int transientFlag, int transparentFlag, int windowState) { int transientFlag, int transparentFlag, int windowState) {
final int oldMode = barMode(oldVis, transientFlag, transparentFlag); final int oldMode = barMode(oldVis, transientFlag, transparentFlag);
@@ -1928,8 +1933,7 @@ public class PhoneStatusBar extends BaseStatusBar {
if (oldMode == newMode) { if (oldMode == newMode) {
return -1; // no mode change return -1; // no mode change
} }
boolean animate = windowState == StatusBarManager.WINDOW_STATE_SHOWING final boolean animate = windowState == StatusBarManager.WINDOW_STATE_SHOWING;
&& oldMode == MODE_SEMI_TRANSPARENT && newMode == MODE_OPAQUE;
transitions.transitionTo(newMode, animate); transitions.transitionTo(newMode, animate);
return newMode; return newMode;
} }

View File

@@ -16,20 +16,26 @@
package com.android.systemui.statusbar.phone; package com.android.systemui.statusbar.phone;
import android.animation.Animator;
import android.animation.AnimatorSet;
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;
import android.content.res.Resources.NotFoundException; import android.content.res.Resources.NotFoundException;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet; import android.util.AttributeSet;
import android.util.EventLog; import android.util.EventLog;
import android.util.Log; import android.util.Log;
import android.view.MotionEvent; import android.view.MotionEvent;
import android.view.View; import android.view.View;
import android.view.ViewGroup;
import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityEvent;
import com.android.systemui.EventLogTags; import com.android.systemui.EventLogTags;
import com.android.systemui.R; import com.android.systemui.R;
import com.android.systemui.statusbar.StatusBarIconView;
import java.util.ArrayList;
import java.util.List;
public class PhoneStatusBarView extends PanelBar { public class PhoneStatusBarView extends PanelBar {
private static final String TAG = "PhoneStatusBarView"; private static final String TAG = "PhoneStatusBarView";
@@ -49,10 +55,56 @@ public class PhoneStatusBarView extends PanelBar {
private final StatusBarTransitions mBarTransitions; private final StatusBarTransitions mBarTransitions;
private final class StatusBarTransitions extends BarTransitions { private final class StatusBarTransitions extends BarTransitions {
private final int mTransparent;
public StatusBarTransitions(Context context) { public StatusBarTransitions(Context context) {
super(context, PhoneStatusBarView.this); super(context, PhoneStatusBarView.this);
final Resources res = context.getResources(); final Resources res = context.getResources();
mTransparent = res.getDrawable(R.color.status_bar_background_transparent); mTransparent = res.getColor(R.color.status_bar_background_transparent);
}
@Override
protected Integer getBackgroundColor(int mode) {
if (mode == MODE_TRANSPARENT) return mTransparent;
return super.getBackgroundColor(mode);
}
@Override
protected void onTransition(int oldMode, int newMode, boolean animate) {
super.onTransition(oldMode, newMode, animate);
if (animate) {
List<Animator> animators = new ArrayList<Animator>();
for(StatusBarIconView icon : findStatusBarIcons()) {
animators.add(icon.animateTransitionTo(newMode));
}
AnimatorSet set = new AnimatorSet();
set.playTogether(animators);
set.start();
} else {
for(StatusBarIconView icon : findStatusBarIcons()) {
icon.setAlpha(icon.getAlphaFor(newMode));
}
}
}
private List<StatusBarIconView> findStatusBarIcons() {
List<StatusBarIconView> icons = new ArrayList<StatusBarIconView>();
findStatusBarIcons(icons, findViewById(R.id.moreIcon));
findStatusBarIcons(icons, findViewById(R.id.statusIcons));
findStatusBarIcons(icons, findViewById(R.id.notificationIcons));
return icons;
}
private void findStatusBarIcons(List<StatusBarIconView> icons, View v) {
if (v instanceof StatusBarIconView) {
icons.add((StatusBarIconView) v);
} else if (v instanceof ViewGroup) {
ViewGroup group = (ViewGroup) v;
final int N = group.getChildCount();
for (int i = 0; i < N; i++) {
findStatusBarIcons(icons, group.getChildAt(i));
}
}
} }
} }

View File

@@ -20,6 +20,7 @@ import android.app.StatusBarManager;
import android.os.Handler; import android.os.Handler;
import android.os.RemoteException; import android.os.RemoteException;
import android.os.ServiceManager; import android.os.ServiceManager;
import android.os.SystemClock;
import android.util.Slog; import android.util.Slog;
import android.view.View; import android.view.View;
import android.view.WindowManagerPolicy.WindowState; import android.view.WindowManagerPolicy.WindowState;
@@ -38,9 +39,12 @@ public class BarController {
private static final int TRANSIENT_BAR_SHOWING = 1; private static final int TRANSIENT_BAR_SHOWING = 1;
private static final int TRANSIENT_BAR_HIDING = 2; private static final int TRANSIENT_BAR_HIDING = 2;
private static final int TRANSPARENT_ANIMATION_DELAY_MS = 1000;
private final String mTag; private final String mTag;
private final int mTransientFlag; private final int mTransientFlag;
private final int mUnhideFlag; private final int mUnhideFlag;
private final int mTransparentFlag;
private final int mStatusBarManagerId; private final int mStatusBarManagerId;
private final Handler mHandler; private final Handler mHandler;
private final Object mServiceAquireLock = new Object(); private final Object mServiceAquireLock = new Object();
@@ -50,11 +54,14 @@ public class BarController {
private int mState; private int mState;
private int mTransientBarState; private int mTransientBarState;
private boolean mPendingShow; private boolean mPendingShow;
private long mLastTransparent;
public BarController(String tag, int transientFlag, int unhideFlag, int statusBarManagerId) { public BarController(String tag, int transientFlag, int unhideFlag, int transparentFlag,
int statusBarManagerId) {
mTag = "BarController." + tag; mTag = "BarController." + tag;
mTransientFlag = transientFlag; mTransientFlag = transientFlag;
mUnhideFlag = unhideFlag; mUnhideFlag = unhideFlag;
mTransparentFlag = transparentFlag;
mStatusBarManagerId = statusBarManagerId; mStatusBarManagerId = statusBarManagerId;
mHandler = new Handler(); mHandler = new Handler();
} }
@@ -77,6 +84,10 @@ public class BarController {
return mTransientBarState == TRANSIENT_BAR_SHOWING; return mTransientBarState == TRANSIENT_BAR_SHOWING;
} }
public boolean wasRecentlyTransparent() {
return (SystemClock.uptimeMillis() - mLastTransparent) < TRANSPARENT_ANIMATION_DELAY_MS;
}
public void adjustSystemUiVisibilityLw(int oldVis, int vis) { public void adjustSystemUiVisibilityLw(int oldVis, int vis) {
if (mWin != null && mTransientBarState == TRANSIENT_BAR_SHOWING && if (mWin != null && mTransientBarState == TRANSIENT_BAR_SHOWING &&
(vis & mTransientFlag) == 0) { (vis & mTransientFlag) == 0) {
@@ -181,11 +192,17 @@ public class BarController {
vis |= mTransientFlag; // ignore clear requests until transition completes vis |= mTransientFlag; // ignore clear requests until transition completes
vis &= ~View.SYSTEM_UI_FLAG_LOW_PROFILE; // never show transient bars in low profile vis &= ~View.SYSTEM_UI_FLAG_LOW_PROFILE; // never show transient bars in low profile
} }
if ((vis & mTransparentFlag) != 0 || (oldVis & mTransparentFlag) != 0) {
mLastTransparent = SystemClock.uptimeMillis();
}
return vis; return vis;
} }
private void setTransientBarState(int state) { private void setTransientBarState(int state) {
if (mWin != null && state != mTransientBarState) { if (mWin != null && state != mTransientBarState) {
if (mTransientBarState == TRANSIENT_BAR_SHOWING || state == TRANSIENT_BAR_SHOWING) {
mLastTransparent = SystemClock.uptimeMillis();
}
mTransientBarState = state; mTransientBarState = state;
if (DEBUG) Slog.d(mTag, "New state: " + transientBarStateToString(state)); if (DEBUG) Slog.d(mTag, "New state: " + transientBarStateToString(state));
} }

View File

@@ -556,11 +556,13 @@ public class PhoneWindowManager implements WindowManagerPolicy {
private final BarController mStatusBarController = new BarController("StatusBar", private final BarController mStatusBarController = new BarController("StatusBar",
View.STATUS_BAR_TRANSIENT, View.STATUS_BAR_TRANSIENT,
View.STATUS_BAR_UNHIDE, View.STATUS_BAR_UNHIDE,
View.SYSTEM_UI_FLAG_TRANSPARENT_STATUS,
StatusBarManager.WINDOW_STATUS_BAR); StatusBarManager.WINDOW_STATUS_BAR);
private final BarController mNavigationBarController = new BarController("NavigationBar", private final BarController mNavigationBarController = new BarController("NavigationBar",
View.NAVIGATION_BAR_TRANSIENT, View.NAVIGATION_BAR_TRANSIENT,
View.NAVIGATION_BAR_UNHIDE, View.NAVIGATION_BAR_UNHIDE,
View.SYSTEM_UI_FLAG_TRANSPARENT_NAVIGATION,
StatusBarManager.WINDOW_NAVIGATION_BAR); StatusBarManager.WINDOW_NAVIGATION_BAR);
private TransientNavigationConfirmation mTransientNavigationConfirmation; private TransientNavigationConfirmation mTransientNavigationConfirmation;
@@ -2739,7 +2741,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {
// We currently want to hide the navigation UI. // We currently want to hide the navigation UI.
mNavigationBarController.setBarShowingLw(false); mNavigationBarController.setBarShowingLw(false);
} }
if (navVisible && !navTransparent && !mNavigationBar.isAnimatingLw()) { if (navVisible && !navTransparent && !mNavigationBar.isAnimatingLw()
&& !mNavigationBarController.wasRecentlyTransparent()) {
// If the opaque nav bar is currently requested to be visible, // If the opaque nav bar is currently requested to be visible,
// and not in the process of animating on or off, then // and not in the process of animating on or off, then
// we can tell the app that it is covered by it. // we can tell the app that it is covered by it.
@@ -2762,7 +2765,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {
// We currently want to hide the navigation UI. // We currently want to hide the navigation UI.
mNavigationBarController.setBarShowingLw(false); mNavigationBarController.setBarShowingLw(false);
} }
if (navVisible && !navTransparent && !mNavigationBar.isAnimatingLw()) { if (navVisible && !navTransparent && !mNavigationBar.isAnimatingLw()
&& !mNavigationBarController.wasRecentlyTransparent()) {
// If the nav bar is currently requested to be visible, // If the nav bar is currently requested to be visible,
// and not in the process of animating on or off, then // and not in the process of animating on or off, then
// we can tell the app that it is covered by it. // we can tell the app that it is covered by it.
@@ -2832,7 +2836,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {
mCurLeft, mCurTop, mCurRight, mCurBottom)); mCurLeft, mCurTop, mCurRight, mCurBottom));
} }
if (mStatusBar.isVisibleLw() && !mStatusBar.isAnimatingLw() if (mStatusBar.isVisibleLw() && !mStatusBar.isAnimatingLw()
&& !statusBarTransient && !statusBarTransparent) { && !statusBarTransient && !statusBarTransparent
&& !mStatusBarController.wasRecentlyTransparent()) {
// If the opaque status bar is currently requested to be visible, // If the opaque status bar is currently requested to be visible,
// and not in the process of animating on or off, then // and not in the process of animating on or off, then
// we can tell the app that it is covered by it. // we can tell the app that it is covered by it.
@@ -5011,7 +5016,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
if (mForcingShowNavBar && mFocusedWindow.getSurfaceLayer() < mForcingShowNavBarLayer) { if (mForcingShowNavBar && mFocusedWindow.getSurfaceLayer() < mForcingShowNavBarLayer) {
tmpVisibility &= ~View.SYSTEM_UI_CLEARABLE_FLAGS; tmpVisibility &= ~View.SYSTEM_UI_CLEARABLE_FLAGS;
} }
final int visibility = updateTransientBarsLw(mLastSystemUiFlags, tmpVisibility); final int visibility = updateSystemBarsLw(mLastSystemUiFlags, tmpVisibility);
final int diff = visibility ^ mLastSystemUiFlags; final int diff = visibility ^ mLastSystemUiFlags;
final boolean needsMenu = mFocusedWindow.getNeedsMenuLw(mTopFullscreenOpaqueWindowState); final boolean needsMenu = mFocusedWindow.getNeedsMenuLw(mTopFullscreenOpaqueWindowState);
if (diff == 0 && mLastFocusNeedsMenu == needsMenu if (diff == 0 && mLastFocusNeedsMenu == needsMenu
@@ -5039,7 +5044,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
return diff; return diff;
} }
private int updateTransientBarsLw(int oldVis, int vis) { private int updateSystemBarsLw(int oldVis, int vis) {
if (ImmersiveModeTesting.enabled) { if (ImmersiveModeTesting.enabled) {
vis = ImmersiveModeTesting.applyForced(mFocusedWindow, vis); vis = ImmersiveModeTesting.applyForced(mFocusedWindow, vis);
} }