Merge "Expand the navbar dead zone briefly after touches elsewhere." into jb-mr1-dev

This commit is contained in:
Daniel Sandler
2012-08-29 20:29:28 -07:00
committed by Android (Google) Code Review
8 changed files with 177 additions and 17 deletions

View File

@@ -143,8 +143,13 @@
<com.android.systemui.statusbar.policy.DeadZone
android:id="@+id/deadzone"
android:layout_height="@dimen/navigation_bar_deadzone_size"
android:layout_height="match_parent"
android:layout_width="match_parent"
systemui:minSize="@dimen/navigation_bar_deadzone_size"
systemui:maxSize="@dimen/navigation_bar_deadzone_size_max"
systemui:holdTime="@integer/navigation_bar_deadzone_hold"
systemui:decayTime="@integer/navigation_bar_deadzone_decay"
systemui:orientation="horizontal"
android:layout_gravity="top"
/>
</FrameLayout>
@@ -269,8 +274,13 @@
<com.android.systemui.statusbar.policy.DeadZone
android:id="@+id/deadzone"
android:layout_height="@dimen/navigation_bar_deadzone_size"
android:layout_height="match_parent"
android:layout_width="match_parent"
systemui:minSize="@dimen/navigation_bar_deadzone_size"
systemui:maxSize="@dimen/navigation_bar_deadzone_size_max"
systemui:holdTime="@integer/navigation_bar_deadzone_hold"
systemui:decayTime="@integer/navigation_bar_deadzone_decay"
systemui:orientation="vertical"
android:layout_gravity="top"
/>
</FrameLayout>

View File

@@ -147,8 +147,13 @@
<com.android.systemui.statusbar.policy.DeadZone
android:id="@+id/deadzone"
android:layout_height="@dimen/navigation_bar_deadzone_size"
android:layout_height="match_parent"
android:layout_width="match_parent"
systemui:minSize="@dimen/navigation_bar_deadzone_size"
systemui:maxSize="@dimen/navigation_bar_deadzone_size_max"
systemui:holdTime="@integer/navigation_bar_deadzone_hold"
systemui:decayTime="@integer/navigation_bar_deadzone_decay"
systemui:orientation="horizontal"
android:layout_gravity="top"
/>
</FrameLayout>
@@ -276,9 +281,14 @@
<com.android.systemui.statusbar.policy.DeadZone
android:id="@+id/deadzone"
android:layout_width="@dimen/navigation_bar_deadzone_size"
android:layout_height="match_parent"
android:layout_gravity="left"
android:layout_width="match_parent"
systemui:minSize="@dimen/navigation_bar_deadzone_size"
systemui:maxSize="@dimen/navigation_bar_deadzone_size_max"
systemui:holdTime="@integer/navigation_bar_deadzone_hold"
systemui:decayTime="@integer/navigation_bar_deadzone_decay"
systemui:orientation="vertical"
android:layout_gravity="top"
/>
</FrameLayout>

View File

@@ -35,5 +35,17 @@
<declare-styleable name="RecentsPanelView">
<attr name="recentItemLayout" format="reference" />
</declare-styleable>
<declare-styleable name="DeadZone">
<attr name="minSize" format="dimension" />
<attr name="maxSize" format="dimension" />
<attr name="holdTime" format="integer" />
<attr name="decayTime" format="integer" />
<attr name="orientation" />
</declare-styleable>
<attr name="orientation">
<enum name="horizontal" value="0" />
<enum name="vertical" value="1" />
</attr>
</resources>

View File

@@ -72,5 +72,9 @@
<!-- Whether we're using the tablet-optimized recents interface (we use this
value at runtime for some things) -->
<integer name="status_bar_recents_bg_gradient_degrees">90</integer>
<!-- decay duration (from size_max -> size), in ms -->
<integer name="navigation_bar_deadzone_hold">333</integer>
<integer name="navigation_bar_deadzone_decay">333</integer>
</resources>

View File

@@ -63,6 +63,8 @@
<!-- thickness (height) of the dead zone at the top of the navigation bar,
reducing false presses on navbar buttons; approx 2mm -->
<dimen name="navigation_bar_deadzone_size">12dp</dimen>
<!-- size of the dead zone when touches have recently occurred elsewhere on screen -->
<dimen name="navigation_bar_deadzone_size_max">32dp</dimen>
<!-- Height of notification icons in the status bar -->
<dimen name="status_bar_icon_size">@*android:dimen/status_bar_icon_size</dimen>

View File

@@ -45,13 +45,12 @@ 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;
public class NavigationBarView extends LinearLayout {
final static boolean DEBUG = false;
final static String TAG = "PhoneStatusBar/NavigationBarView";
final static boolean DEBUG_DEADZONE = false;
final static boolean NAVBAR_ALWAYS_AT_RIGHT = true;
final static boolean ANIMATE_HIDE_TRANSITION = false; // turned off because it introduces unsightly delay when videos goes to full screen
@@ -71,6 +70,7 @@ public class NavigationBarView extends LinearLayout {
private Drawable mBackIcon, mBackLandIcon, mBackAltIcon, mBackAltLandIcon;
private DelegateViewHelper mDelegateHelper;
private DeadZone mDeadZone;
// workaround for LayoutTransitions leaving the nav buttons in a weird state (bug 5549288)
final static boolean WORKAROUND_INVALID_LAYOUT = true;
@@ -109,10 +109,14 @@ public class NavigationBarView extends LinearLayout {
@Override
public boolean onTouchEvent(MotionEvent event) {
if (mDelegateHelper != null) {
mDelegateHelper.onInterceptTouchEvent(event);
if (mDeadZone != null && event.getAction() == MotionEvent.ACTION_OUTSIDE) {
mDeadZone.poke(event);
}
return true;
if (mDelegateHelper != null) {
boolean ret = mDelegateHelper.onInterceptTouchEvent(event);
if (ret) return true;
}
return super.onTouchEvent(event);
}
@Override
@@ -335,15 +339,13 @@ public class NavigationBarView extends LinearLayout {
mCurrentView = mRotatedViews[rot];
mCurrentView.setVisibility(View.VISIBLE);
mDeadZone = (DeadZone) mCurrentView.findViewById(R.id.deadzone);
// force the low profile & disabled states into compliance
setLowProfile(mLowProfile, false, true /* force */);
setDisabledFlags(mDisabledFlags, true /* force */);
setMenuVisibility(mShowMenu, true /* force */);
if (DEBUG_DEADZONE) {
mCurrentView.findViewById(R.id.deadzone).setBackgroundColor(0x808080FF);
}
if (DEBUG) {
Slog.d(TAG, "reorient(): rot=" + mDisplay.getRotation());
}

View File

@@ -639,6 +639,7 @@ public class PhoneStatusBar extends BaseStatusBar {
| WindowManager.LayoutParams.FLAG_TOUCHABLE_WHEN_WAKING
| WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
| WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
| WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
| WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
PixelFormat.OPAQUE);
// this will allow the navbar to run in an overlay on devices that support this

View File

@@ -16,26 +16,145 @@
package com.android.systemui.statusbar.policy;
import android.animation.ObjectAnimator;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.os.SystemClock;
import android.util.AttributeSet;
import android.util.Slog;
import android.view.MotionEvent;
import android.view.View;
import com.android.systemui.R;
public class DeadZone extends View {
public static final String TAG = "DeadZone";
public static final boolean DEBUG = false;
public static final int HORIZONTAL = 0;
public static final int VERTICAL = 1;
private boolean mShouldFlash;
private float mFlashFrac = 0f;
private int mSizeMax;
private int mSizeMin;
// Upon activity elsewhere in the UI, the dead zone will hold steady for
// mHold ms, then move back over the course of mDecay ms
private int mHold, mDecay;
private boolean mVertical;
private long mLastPokeTime;
private final Runnable mDebugFlash = new Runnable() {
@Override
public void run() {
ObjectAnimator.ofFloat(DeadZone.this, "flash", 1f, 0f).setDuration(150).start();
}
};
public DeadZone(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public DeadZone(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs);
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.DeadZone,
defStyle, 0);
mHold = a.getInteger(R.styleable.DeadZone_holdTime, 0);
mDecay = a.getInteger(R.styleable.DeadZone_decayTime, 0);
mSizeMin = a.getDimensionPixelSize(R.styleable.DeadZone_minSize, 0);
mSizeMax = a.getDimensionPixelSize(R.styleable.DeadZone_maxSize, 0);
int index = a.getInt(R.styleable.DeadZone_orientation, -1);
mVertical = (index == VERTICAL);
if (DEBUG)
Slog.v(TAG, this + " size=[" + mSizeMin + "-" + mSizeMax + "] hold=" + mHold
+ (mVertical ? " vertical" : " horizontal"));
setFlashOnTouchCapture(true);
}
static float lerp(float a, float b, float f) {
return (b - a) * f + a;
}
private float getSize(long now) {
if (mSizeMax == 0)
return 0;
long dt = (now - mLastPokeTime);
if (dt > mHold + mDecay)
return mSizeMin;
if (dt < mHold)
return mSizeMax;
return (int) lerp(mSizeMax, mSizeMin, (float) (dt - mHold) / mDecay);
}
public void setFlashOnTouchCapture(boolean dbg) {
mShouldFlash = dbg;
mFlashFrac = 0f;
postInvalidate();
}
// I made you a touch event
@Override
public boolean onTouchEvent (MotionEvent event) {
return true; // but I eated it
public boolean onTouchEvent(MotionEvent event) {
if (DEBUG)
Slog.v(TAG, this + " onTouch: " + MotionEvent.actionToString(event.getAction()));
final int action = event.getAction();
if (action == MotionEvent.ACTION_OUTSIDE) {
poke(event);
} else if (action == MotionEvent.ACTION_DOWN) {
if (DEBUG)
Slog.v(TAG, this + " ACTION_DOWN: " + event.getX() + "," + event.getY());
int size = (int) getSize(event.getEventTime());
if ((mVertical && event.getX() < size) || event.getY() < size) {
if (DEBUG)
Slog.v(TAG, "eating click!");
if (mShouldFlash) {
post(mDebugFlash);
postInvalidate();
}
return true; // but I eated it
}
}
return false;
}
public void poke(MotionEvent event) {
mLastPokeTime = event.getEventTime();
if (DEBUG)
Slog.v(TAG, "poked! size=" + getSize(mLastPokeTime));
postInvalidate();
}
public void setFlash(float f) {
mFlashFrac = f;
postInvalidate();
}
public float getFlash() {
return mFlashFrac;
}
@Override
public void onDraw(Canvas can) {
if (!mShouldFlash || mFlashFrac <= 0f) {
return;
}
final int size = (int) getSize(SystemClock.uptimeMillis());
can.clipRect(0, 0, mVertical ? size : can.getWidth(), mVertical ? can.getHeight() : size);
final float frac = DEBUG ? (mFlashFrac - 0.5f) + 0.5f : mFlashFrac;
can.drawARGB((int) (frac * 0xFF), 0xDD, 0xEE, 0xAA);
if (DEBUG && size > mSizeMin)
// crazy aggressive redrawing here, for debugging only
postInvalidateDelayed(100);
}
}