2323import android .content .Context ;
2424import android .content .res .Resources ;
2525import android .graphics .Rect ;
26+ import android .os .Handler ;
27+ import android .os .Message ;
2628import android .os .ServiceManager ;
2729import android .util .AttributeSet ;
2830import android .util .Slog ;
@@ -66,6 +68,35 @@ public class NavigationBarView extends LinearLayout {
6668 int mDisabledFlags = 0 ;
6769 int mNavigationIconHints = 0 ;
6870
71+ // workaround for LayoutTransitions leaving the nav buttons in a weird state (bug 5549288)
72+ final static boolean WORKAROUND_INVALID_LAYOUT = true ;
73+ final static int MSG_CHECK_INVALID_LAYOUT = 8686 ;
74+
75+ private class H extends Handler {
76+ public void handleMessage (Message m ) {
77+ switch (m .what ) {
78+ case MSG_CHECK_INVALID_LAYOUT :
79+ final String how = "" + m .obj ;
80+ final int w = getWidth ();
81+ final int h = getHeight ();
82+ final int vw = mCurrentView .getWidth ();
83+ final int vh = mCurrentView .getHeight ();
84+
85+ if (h != vh || w != vw ) {
86+ Slog .w (TAG , String .format (
87+ "*** Invalid layout in navigation bar (%s this=%dx%d cur=%dx%d)" ,
88+ how , w , h , vw , vh ));
89+ if (WORKAROUND_INVALID_LAYOUT ) {
90+ requestLayout ();
91+ }
92+ }
93+ break ;
94+ }
95+ }
96+ }
97+
98+ private H mHandler = new H ();
99+
69100 public View getRecentsButton () {
70101 return mCurrentView .findViewById (R .id .recent_apps );
71102 }
@@ -275,6 +306,36 @@ public void reorient() {
275306 }
276307 }
277308
309+ @ Override
310+ protected void onSizeChanged (int w , int h , int oldw , int oldh ) {
311+ if (DEBUG ) Slog .d (TAG , String .format (
312+ "onSizeChanged: (%dx%d) old: (%dx%d)" , w , h , oldw , oldh ));
313+ postCheckForInvalidLayout ("sizeChanged" );
314+ super .onSizeChanged (w , h , oldw , oldh );
315+ }
316+
317+ /*
318+ @Override
319+ protected void onLayout (boolean changed, int left, int top, int right, int bottom) {
320+ if (DEBUG) Slog.d(TAG, String.format(
321+ "onLayout: %s (%d,%d,%d,%d)",
322+ changed?"changed":"notchanged", left, top, right, bottom));
323+ super.onLayout(changed, left, top, right, bottom);
324+ }
325+
326+ // uncomment this for extra defensiveness in WORKAROUND_INVALID_LAYOUT situations: if all else
327+ // fails, any touch on the display will fix the layout.
328+ @Override
329+ public boolean onInterceptTouchEvent(MotionEvent ev) {
330+ if (DEBUG) Slog.d(TAG, "onInterceptTouchEvent: " + ev.toString());
331+ if (ev.getAction() == MotionEvent.ACTION_DOWN) {
332+ postCheckForInvalidLayout("touch");
333+ }
334+ return super.onInterceptTouchEvent(ev);
335+ }
336+ */
337+
338+
278339 private String getResourceName (int resId ) {
279340 if (resId != 0 ) {
280341 final android .content .res .Resources res = mContext .getResources ();
@@ -288,6 +349,10 @@ private String getResourceName(int resId) {
288349 }
289350 }
290351
352+ private void postCheckForInvalidLayout (final String how ) {
353+ mHandler .obtainMessage (MSG_CHECK_INVALID_LAYOUT , 0 , 0 , how ).sendToTarget ();
354+ }
355+
291356 private static String visibilityToString (int vis ) {
292357 switch (vis ) {
293358 case View .INVISIBLE :
0 commit comments