Skip to content

Commit 8601e8b

Browse files
dsandlerAndroid (Google) Code Review
authored andcommitted
Merge "Expand the navbar dead zone briefly after touches elsewhere." into jb-mr1-dev
2 parents 5b81de4 + c26185b commit 8601e8b

File tree

8 files changed

+176
-16
lines changed

8 files changed

+176
-16
lines changed

packages/SystemUI/res/layout-sw600dp/navigation_bar.xml

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -143,8 +143,13 @@
143143

144144
<com.android.systemui.statusbar.policy.DeadZone
145145
android:id="@+id/deadzone"
146-
android:layout_height="@dimen/navigation_bar_deadzone_size"
146+
android:layout_height="match_parent"
147147
android:layout_width="match_parent"
148+
systemui:minSize="@dimen/navigation_bar_deadzone_size"
149+
systemui:maxSize="@dimen/navigation_bar_deadzone_size_max"
150+
systemui:holdTime="@integer/navigation_bar_deadzone_hold"
151+
systemui:decayTime="@integer/navigation_bar_deadzone_decay"
152+
systemui:orientation="horizontal"
148153
android:layout_gravity="top"
149154
/>
150155
</FrameLayout>
@@ -269,8 +274,13 @@
269274

270275
<com.android.systemui.statusbar.policy.DeadZone
271276
android:id="@+id/deadzone"
272-
android:layout_height="@dimen/navigation_bar_deadzone_size"
277+
android:layout_height="match_parent"
273278
android:layout_width="match_parent"
279+
systemui:minSize="@dimen/navigation_bar_deadzone_size"
280+
systemui:maxSize="@dimen/navigation_bar_deadzone_size_max"
281+
systemui:holdTime="@integer/navigation_bar_deadzone_hold"
282+
systemui:decayTime="@integer/navigation_bar_deadzone_decay"
283+
systemui:orientation="vertical"
274284
android:layout_gravity="top"
275285
/>
276286
</FrameLayout>

packages/SystemUI/res/layout/navigation_bar.xml

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -147,8 +147,13 @@
147147

148148
<com.android.systemui.statusbar.policy.DeadZone
149149
android:id="@+id/deadzone"
150-
android:layout_height="@dimen/navigation_bar_deadzone_size"
150+
android:layout_height="match_parent"
151151
android:layout_width="match_parent"
152+
systemui:minSize="@dimen/navigation_bar_deadzone_size"
153+
systemui:maxSize="@dimen/navigation_bar_deadzone_size_max"
154+
systemui:holdTime="@integer/navigation_bar_deadzone_hold"
155+
systemui:decayTime="@integer/navigation_bar_deadzone_decay"
156+
systemui:orientation="horizontal"
152157
android:layout_gravity="top"
153158
/>
154159
</FrameLayout>
@@ -276,9 +281,14 @@
276281

277282
<com.android.systemui.statusbar.policy.DeadZone
278283
android:id="@+id/deadzone"
279-
android:layout_width="@dimen/navigation_bar_deadzone_size"
280284
android:layout_height="match_parent"
281-
android:layout_gravity="left"
285+
android:layout_width="match_parent"
286+
systemui:minSize="@dimen/navigation_bar_deadzone_size"
287+
systemui:maxSize="@dimen/navigation_bar_deadzone_size_max"
288+
systemui:holdTime="@integer/navigation_bar_deadzone_hold"
289+
systemui:decayTime="@integer/navigation_bar_deadzone_decay"
290+
systemui:orientation="vertical"
291+
android:layout_gravity="top"
282292
/>
283293
</FrameLayout>
284294

packages/SystemUI/res/values/attrs.xml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,5 +35,17 @@
3535
<declare-styleable name="RecentsPanelView">
3636
<attr name="recentItemLayout" format="reference" />
3737
</declare-styleable>
38+
<declare-styleable name="DeadZone">
39+
<attr name="minSize" format="dimension" />
40+
<attr name="maxSize" format="dimension" />
41+
<attr name="holdTime" format="integer" />
42+
<attr name="decayTime" format="integer" />
43+
<attr name="orientation" />
44+
</declare-styleable>
45+
46+
<attr name="orientation">
47+
<enum name="horizontal" value="0" />
48+
<enum name="vertical" value="1" />
49+
</attr>
3850
</resources>
3951

packages/SystemUI/res/values/config.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,5 +72,9 @@
7272
<!-- Whether we're using the tablet-optimized recents interface (we use this
7373
value at runtime for some things) -->
7474
<integer name="status_bar_recents_bg_gradient_degrees">90</integer>
75+
76+
<!-- decay duration (from size_max -> size), in ms -->
77+
<integer name="navigation_bar_deadzone_hold">333</integer>
78+
<integer name="navigation_bar_deadzone_decay">333</integer>
7579
</resources>
7680

packages/SystemUI/res/values/dimens.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,8 @@
6363
<!-- thickness (height) of the dead zone at the top of the navigation bar,
6464
reducing false presses on navbar buttons; approx 2mm -->
6565
<dimen name="navigation_bar_deadzone_size">12dp</dimen>
66+
<!-- size of the dead zone when touches have recently occurred elsewhere on screen -->
67+
<dimen name="navigation_bar_deadzone_size_max">32dp</dimen>
6668

6769
<!-- Height of notification icons in the status bar -->
6870
<dimen name="status_bar_icon_size">@*android:dimen/status_bar_icon_size</dimen>

packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -45,13 +45,12 @@
4545
import com.android.systemui.R;
4646
import com.android.systemui.statusbar.BaseStatusBar;
4747
import com.android.systemui.statusbar.DelegateViewHelper;
48+
import com.android.systemui.statusbar.policy.DeadZone;
4849

4950
public class NavigationBarView extends LinearLayout {
5051
final static boolean DEBUG = false;
5152
final static String TAG = "PhoneStatusBar/NavigationBarView";
5253

53-
final static boolean DEBUG_DEADZONE = false;
54-
5554
final static boolean NAVBAR_ALWAYS_AT_RIGHT = true;
5655

5756
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 {
7170
private Drawable mBackIcon, mBackLandIcon, mBackAltIcon, mBackAltLandIcon;
7271

7372
private DelegateViewHelper mDelegateHelper;
73+
private DeadZone mDeadZone;
7474

7575
// workaround for LayoutTransitions leaving the nav buttons in a weird state (bug 5549288)
7676
final static boolean WORKAROUND_INVALID_LAYOUT = true;
@@ -109,10 +109,14 @@ public void setBar(BaseStatusBar phoneStatusBar) {
109109

110110
@Override
111111
public boolean onTouchEvent(MotionEvent event) {
112+
if (mDeadZone != null && event.getAction() == MotionEvent.ACTION_OUTSIDE) {
113+
mDeadZone.poke(event);
114+
}
112115
if (mDelegateHelper != null) {
113-
mDelegateHelper.onInterceptTouchEvent(event);
116+
boolean ret = mDelegateHelper.onInterceptTouchEvent(event);
117+
if (ret) return true;
114118
}
115-
return true;
119+
return super.onTouchEvent(event);
116120
}
117121

118122
@Override
@@ -335,15 +339,13 @@ public void reorient() {
335339
mCurrentView = mRotatedViews[rot];
336340
mCurrentView.setVisibility(View.VISIBLE);
337341

342+
mDeadZone = (DeadZone) mCurrentView.findViewById(R.id.deadzone);
343+
338344
// force the low profile & disabled states into compliance
339345
setLowProfile(mLowProfile, false, true /* force */);
340346
setDisabledFlags(mDisabledFlags, true /* force */);
341347
setMenuVisibility(mShowMenu, true /* force */);
342348

343-
if (DEBUG_DEADZONE) {
344-
mCurrentView.findViewById(R.id.deadzone).setBackgroundColor(0x808080FF);
345-
}
346-
347349
if (DEBUG) {
348350
Slog.d(TAG, "reorient(): rot=" + mDisplay.getRotation());
349351
}

packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -639,6 +639,7 @@ private WindowManager.LayoutParams getNavigationBarLayoutParams() {
639639
| WindowManager.LayoutParams.FLAG_TOUCHABLE_WHEN_WAKING
640640
| WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
641641
| WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
642+
| WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
642643
| WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
643644
PixelFormat.OPAQUE);
644645
// this will allow the navbar to run in an overlay on devices that support this

packages/SystemUI/src/com/android/systemui/statusbar/policy/DeadZone.java

Lines changed: 122 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,26 +16,145 @@
1616

1717
package com.android.systemui.statusbar.policy;
1818

19+
import android.animation.ObjectAnimator;
1920
import android.content.Context;
21+
import android.content.res.TypedArray;
22+
import android.graphics.Canvas;
23+
import android.os.SystemClock;
2024
import android.util.AttributeSet;
25+
import android.util.Slog;
2126
import android.view.MotionEvent;
2227
import android.view.View;
2328

2429
import com.android.systemui.R;
2530

2631
public class DeadZone extends View {
32+
public static final String TAG = "DeadZone";
33+
34+
public static final boolean DEBUG = false;
35+
public static final int HORIZONTAL = 0;
36+
public static final int VERTICAL = 1;
37+
38+
private boolean mShouldFlash;
39+
private float mFlashFrac = 0f;
40+
41+
private int mSizeMax;
42+
private int mSizeMin;
43+
// Upon activity elsewhere in the UI, the dead zone will hold steady for
44+
// mHold ms, then move back over the course of mDecay ms
45+
private int mHold, mDecay;
46+
private boolean mVertical;
47+
private long mLastPokeTime;
48+
49+
private final Runnable mDebugFlash = new Runnable() {
50+
@Override
51+
public void run() {
52+
ObjectAnimator.ofFloat(DeadZone.this, "flash", 1f, 0f).setDuration(150).start();
53+
}
54+
};
55+
2756
public DeadZone(Context context, AttributeSet attrs) {
2857
this(context, attrs, 0);
2958
}
3059

3160
public DeadZone(Context context, AttributeSet attrs, int defStyle) {
3261
super(context, attrs);
62+
63+
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.DeadZone,
64+
defStyle, 0);
65+
66+
mHold = a.getInteger(R.styleable.DeadZone_holdTime, 0);
67+
mDecay = a.getInteger(R.styleable.DeadZone_decayTime, 0);
68+
69+
mSizeMin = a.getDimensionPixelSize(R.styleable.DeadZone_minSize, 0);
70+
mSizeMax = a.getDimensionPixelSize(R.styleable.DeadZone_maxSize, 0);
71+
72+
int index = a.getInt(R.styleable.DeadZone_orientation, -1);
73+
mVertical = (index == VERTICAL);
74+
75+
if (DEBUG)
76+
Slog.v(TAG, this + " size=[" + mSizeMin + "-" + mSizeMax + "] hold=" + mHold
77+
+ (mVertical ? " vertical" : " horizontal"));
78+
79+
setFlashOnTouchCapture(true);
80+
}
81+
82+
static float lerp(float a, float b, float f) {
83+
return (b - a) * f + a;
84+
}
85+
86+
private float getSize(long now) {
87+
if (mSizeMax == 0)
88+
return 0;
89+
long dt = (now - mLastPokeTime);
90+
if (dt > mHold + mDecay)
91+
return mSizeMin;
92+
if (dt < mHold)
93+
return mSizeMax;
94+
return (int) lerp(mSizeMax, mSizeMin, (float) (dt - mHold) / mDecay);
95+
}
96+
97+
public void setFlashOnTouchCapture(boolean dbg) {
98+
mShouldFlash = dbg;
99+
mFlashFrac = 0f;
100+
postInvalidate();
33101
}
34102

35103
// I made you a touch event
36104
@Override
37-
public boolean onTouchEvent (MotionEvent event) {
38-
return true; // but I eated it
105+
public boolean onTouchEvent(MotionEvent event) {
106+
if (DEBUG)
107+
Slog.v(TAG, this + " onTouch: " + MotionEvent.actionToString(event.getAction()));
108+
109+
final int action = event.getAction();
110+
if (action == MotionEvent.ACTION_OUTSIDE) {
111+
poke(event);
112+
} else if (action == MotionEvent.ACTION_DOWN) {
113+
if (DEBUG)
114+
Slog.v(TAG, this + " ACTION_DOWN: " + event.getX() + "," + event.getY());
115+
int size = (int) getSize(event.getEventTime());
116+
if ((mVertical && event.getX() < size) || event.getY() < size) {
117+
if (DEBUG)
118+
Slog.v(TAG, "eating click!");
119+
if (mShouldFlash) {
120+
post(mDebugFlash);
121+
postInvalidate();
122+
}
123+
return true; // but I eated it
124+
}
125+
}
126+
return false;
127+
}
128+
129+
public void poke(MotionEvent event) {
130+
mLastPokeTime = event.getEventTime();
131+
if (DEBUG)
132+
Slog.v(TAG, "poked! size=" + getSize(mLastPokeTime));
133+
postInvalidate();
134+
}
135+
136+
public void setFlash(float f) {
137+
mFlashFrac = f;
138+
postInvalidate();
39139
}
40-
}
41140

141+
public float getFlash() {
142+
return mFlashFrac;
143+
}
144+
145+
@Override
146+
public void onDraw(Canvas can) {
147+
if (!mShouldFlash || mFlashFrac <= 0f) {
148+
return;
149+
}
150+
151+
final int size = (int) getSize(SystemClock.uptimeMillis());
152+
can.clipRect(0, 0, mVertical ? size : can.getWidth(), mVertical ? can.getHeight() : size);
153+
final float frac = DEBUG ? (mFlashFrac - 0.5f) + 0.5f : mFlashFrac;
154+
can.drawARGB((int) (frac * 0xFF), 0xDD, 0xEE, 0xAA);
155+
156+
if (DEBUG && size > mSizeMin)
157+
// crazy aggressive redrawing here, for debugging only
158+
postInvalidateDelayed(100);
159+
}
160+
}

0 commit comments

Comments
 (0)