Skip to content

Commit 0b69b59

Browse files
committed
Detect and repair invalid layouts in the navigation bar.
It seems that something (probably layout transitions) occasionally leaves the navigation bar layout in a weird state such that most of the buttons are offscreen. For example, the portrait nav bar might have buttons with widths matching the nav bar's old width from landscape; the clickable regions will therefore be far off the right edge of the display. The navigation bar now looks for this situation when the size of the view changes and corrects for it. Bug: 5549288 Change-Id: I8464ac9fd64cb64ec18baf51478dd0f6564a2284
1 parent 5e5b57a commit 0b69b59

File tree

1 file changed

+65
-0
lines changed

1 file changed

+65
-0
lines changed

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

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
import android.content.Context;
2222
import android.content.res.Resources;
2323
import android.graphics.Rect;
24+
import android.os.Handler;
25+
import android.os.Message;
2426
import android.os.ServiceManager;
2527
import android.util.AttributeSet;
2628
import android.util.Slog;
@@ -62,6 +64,35 @@ public class NavigationBarView extends LinearLayout {
6264
boolean mHidden, mLowProfile, mShowMenu;
6365
int mDisabledFlags = 0;
6466

67+
// workaround for LayoutTransitions leaving the nav buttons in a weird state (bug 5549288)
68+
final static boolean WORKAROUND_INVALID_LAYOUT = true;
69+
final static int MSG_CHECK_INVALID_LAYOUT = 8686;
70+
71+
private class H extends Handler {
72+
public void handleMessage(Message m) {
73+
switch (m.what) {
74+
case MSG_CHECK_INVALID_LAYOUT:
75+
final String how = "" + m.obj;
76+
final int w = getWidth();
77+
final int h = getHeight();
78+
final int vw = mCurrentView.getWidth();
79+
final int vh = mCurrentView.getHeight();
80+
81+
if (h != vh || w != vw) {
82+
Slog.w(TAG, String.format(
83+
"*** Invalid layout in navigation bar (%s this=%dx%d cur=%dx%d)",
84+
how, w, h, vw, vh));
85+
if (WORKAROUND_INVALID_LAYOUT) {
86+
requestLayout();
87+
}
88+
}
89+
break;
90+
}
91+
}
92+
}
93+
94+
private H mHandler = new H();
95+
6596
public View getRecentsButton() {
6697
return mCurrentView.findViewById(R.id.recent_apps);
6798
}
@@ -243,6 +274,36 @@ public void reorient() {
243274
}
244275
}
245276

277+
@Override
278+
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
279+
if (DEBUG) Slog.d(TAG, String.format(
280+
"onSizeChanged: (%dx%d) old: (%dx%d)", w, h, oldw, oldh));
281+
postCheckForInvalidLayout("sizeChanged");
282+
super.onSizeChanged(w, h, oldw, oldh);
283+
}
284+
285+
/*
286+
@Override
287+
protected void onLayout (boolean changed, int left, int top, int right, int bottom) {
288+
if (DEBUG) Slog.d(TAG, String.format(
289+
"onLayout: %s (%d,%d,%d,%d)",
290+
changed?"changed":"notchanged", left, top, right, bottom));
291+
super.onLayout(changed, left, top, right, bottom);
292+
}
293+
294+
// uncomment this for extra defensiveness in WORKAROUND_INVALID_LAYOUT situations: if all else
295+
// fails, any touch on the display will fix the layout.
296+
@Override
297+
public boolean onInterceptTouchEvent(MotionEvent ev) {
298+
if (DEBUG) Slog.d(TAG, "onInterceptTouchEvent: " + ev.toString());
299+
if (ev.getAction() == MotionEvent.ACTION_DOWN) {
300+
postCheckForInvalidLayout("touch");
301+
}
302+
return super.onInterceptTouchEvent(ev);
303+
}
304+
*/
305+
306+
246307
private String getResourceName(int resId) {
247308
if (resId != 0) {
248309
final android.content.res.Resources res = mContext.getResources();
@@ -256,6 +317,10 @@ private String getResourceName(int resId) {
256317
}
257318
}
258319

320+
private void postCheckForInvalidLayout(final String how) {
321+
mHandler.obtainMessage(MSG_CHECK_INVALID_LAYOUT, 0, 0, how).sendToTarget();
322+
}
323+
259324
private static String visibilityToString(int vis) {
260325
switch (vis) {
261326
case View.INVISIBLE:

0 commit comments

Comments
 (0)