@@ -353,8 +353,13 @@ public void handleMotion(MotionEvent event, InputQueue.FinishedCallback finished
353353 int mDockLeft , mDockTop , mDockRight , mDockBottom ;
354354 // During layout, the layer at which the doc window is placed.
355355 int mDockLayer ;
356- int mLastSystemUiVisibility ;
357- int mForceClearingStatusBarVisibility = 0 ;
356+ int mLastSystemUiFlags ;
357+ // Bits that we are in the process of clearing, so we want to prevent
358+ // them from being set by applications until everything has been updated
359+ // to have them clear.
360+ int mResettingSystemUiFlags = 0 ;
361+ // Bits that we are currently always keeping cleared.
362+ int mForceClearedSystemUiFlags = 0 ;
358363
359364 FakeWindow mHideNavFakeWindow = null ;
360365
@@ -1719,6 +1724,21 @@ public void onKeyguardExitResult(boolean success) {
17191724 }
17201725 }
17211726
1727+ /**
1728+ * A delayed callback use to determine when it is okay to re-allow applications
1729+ * to use certain system UI flags. This is used to prevent applications from
1730+ * spamming system UI changes that prevent the navigation bar from being shown.
1731+ */
1732+ final Runnable mAllowSystemUiDelay = new Runnable () {
1733+ @ Override public void run () {
1734+ }
1735+ };
1736+
1737+ /**
1738+ * Input handler used while nav bar is hidden. Captures any touch on the screen,
1739+ * to determine when the nav bar should be shown and prevent applications from
1740+ * receiving those touches.
1741+ */
17221742 final InputHandler mHideNavInputHandler = new BaseInputHandler () {
17231743 @ Override
17241744 public void handleMotion (MotionEvent event , InputQueue .FinishedCallback finishedCallback ) {
@@ -1731,11 +1751,29 @@ public void handleMotion(MotionEvent event, InputQueue.FinishedCallback finished
17311751 synchronized (mLock ) {
17321752 // Any user activity always causes us to show the navigation controls,
17331753 // if they had been hidden.
1734- int newVal = mForceClearingStatusBarVisibility
1754+ int newVal = mResettingSystemUiFlags
1755+ | View .SYSTEM_UI_FLAG_HIDE_NAVIGATION ;
1756+ if (mResettingSystemUiFlags != newVal ) {
1757+ mResettingSystemUiFlags = newVal ;
1758+ changed = true ;
1759+ }
1760+ // We don't allow the system's nav bar to be hidden
1761+ // again for 1 second, to prevent applications from
1762+ // spamming us and keeping it from being shown.
1763+ newVal = mForceClearedSystemUiFlags
17351764 | View .SYSTEM_UI_FLAG_HIDE_NAVIGATION ;
1736- if (mForceClearingStatusBarVisibility != newVal ) {
1737- mForceClearingStatusBarVisibility = newVal ;
1765+ if (mForceClearedSystemUiFlags != newVal ) {
1766+ mForceClearedSystemUiFlags = newVal ;
17381767 changed = true ;
1768+ mHandler .postDelayed (new Runnable () {
1769+ @ Override public void run () {
1770+ synchronized (mLock ) {
1771+ mForceClearedSystemUiFlags &=
1772+ ~View .SYSTEM_UI_FLAG_HIDE_NAVIGATION ;
1773+ }
1774+ mWindowManagerFuncs .reevaluateStatusBarVisibility ();
1775+ }
1776+ }, 1000 );
17391777 }
17401778 }
17411779 if (changed ) {
@@ -1753,10 +1791,11 @@ public void handleMotion(MotionEvent event, InputQueue.FinishedCallback finished
17531791 public int adjustSystemUiVisibilityLw (int visibility ) {
17541792 // Reset any bits in mForceClearingStatusBarVisibility that
17551793 // are now clear.
1756- mForceClearingStatusBarVisibility &= visibility ;
1794+ mResettingSystemUiFlags &= visibility ;
17571795 // Clear any bits in the new visibility that are currently being
17581796 // force cleared, before reporting it.
1759- return visibility & ~mForceClearingStatusBarVisibility ;
1797+ return visibility & ~mResettingSystemUiFlags
1798+ & ~mForceClearedSystemUiFlags ;
17601799 }
17611800
17621801 public void getContentInsetHintLw (WindowManager .LayoutParams attrs , Rect contentInset ) {
@@ -1795,11 +1834,28 @@ public void beginLayoutLw(int displayWidth, int displayHeight, int displayRotati
17951834 pf .right = df .right = vf .right = mDockRight ;
17961835 pf .bottom = df .bottom = vf .bottom = mDockBottom ;
17971836
1837+ final boolean navVisible = mNavigationBar != null && mNavigationBar .isVisibleLw () &&
1838+ (mLastSystemUiFlags &View .SYSTEM_UI_FLAG_HIDE_NAVIGATION ) == 0 ;
1839+
1840+ // When the navigation bar isn't visible, we put up a fake
1841+ // input window to catch all touch events. This way we can
1842+ // detect when the user presses anywhere to bring back the nav
1843+ // bar and ensure the application doesn't see the event.
1844+ if (navVisible ) {
1845+ if (mHideNavFakeWindow != null ) {
1846+ mHideNavFakeWindow .dismiss ();
1847+ mHideNavFakeWindow = null ;
1848+ }
1849+ } else if (mHideNavFakeWindow == null ) {
1850+ mHideNavFakeWindow = mWindowManagerFuncs .addFakeWindow (
1851+ mHandler .getLooper (), mHideNavInputHandler ,
1852+ "hidden nav" , WindowManager .LayoutParams .TYPE_HIDDEN_NAV_CONSUMER ,
1853+ 0 , false , false , true );
1854+ }
1855+
17981856 // decide where the status bar goes ahead of time
17991857 if (mStatusBar != null ) {
18001858 if (mNavigationBar != null ) {
1801- final boolean navVisible = mNavigationBar .isVisibleLw () &&
1802- (mLastSystemUiVisibility &View .SYSTEM_UI_FLAG_HIDE_NAVIGATION ) == 0 ;
18031859 // Force the navigation bar to its appropriate place and
18041860 // size. We need to do this directly, instead of relying on
18051861 // it to bubble up from the nav bar, because this needs to
@@ -1831,21 +1887,6 @@ public void beginLayoutLw(int displayWidth, int displayHeight, int displayRotati
18311887 mTmpNavigationFrame .offset (mNavigationBarWidth , 0 );
18321888 }
18331889 }
1834- // When the navigation bar isn't visible, we put up a fake
1835- // input window to catch all touch events. This way we can
1836- // detect when the user presses anywhere to bring back the nav
1837- // bar and ensure the application doesn't see the event.
1838- if (navVisible ) {
1839- if (mHideNavFakeWindow != null ) {
1840- mHideNavFakeWindow .dismiss ();
1841- mHideNavFakeWindow = null ;
1842- }
1843- } else if (mHideNavFakeWindow == null ) {
1844- mHideNavFakeWindow = mWindowManagerFuncs .addFakeWindow (
1845- mHandler .getLooper (), mHideNavInputHandler ,
1846- "hidden nav" , WindowManager .LayoutParams .TYPE_HIDDEN_NAV_CONSUMER ,
1847- 0 , false , false , true );
1848- }
18491890 // And compute the final frame.
18501891 mNavigationBar .computeFrameLw (mTmpNavigationFrame , mTmpNavigationFrame ,
18511892 mTmpNavigationFrame , mTmpNavigationFrame );
@@ -3653,12 +3694,13 @@ private int updateSystemUiVisibilityLw() {
36533694 return 0 ;
36543695 }
36553696 final int visibility = mFocusedWindow .getSystemUiVisibility ()
3656- & ~mForceClearingStatusBarVisibility ;
3657- int diff = visibility ^ mLastSystemUiVisibility ;
3697+ & ~mResettingSystemUiFlags
3698+ & ~mForceClearedSystemUiFlags ;
3699+ int diff = visibility ^ mLastSystemUiFlags ;
36583700 if (diff == 0 ) {
36593701 return 0 ;
36603702 }
3661- mLastSystemUiVisibility = visibility ;
3703+ mLastSystemUiFlags = visibility ;
36623704 mHandler .post (new Runnable () {
36633705 public void run () {
36643706 if (mStatusBarService == null ) {
@@ -3685,11 +3727,14 @@ public void dump(String prefix, FileDescriptor fd, PrintWriter pw, String[] args
36853727 pw .print (prefix ); pw .print ("mLidOpen=" ); pw .print (mLidOpen );
36863728 pw .print (" mLidOpenRotation=" ); pw .print (mLidOpenRotation );
36873729 pw .print (" mHdmiPlugged=" ); pw .println (mHdmiPlugged );
3688- if (mLastSystemUiVisibility != 0 || mForceClearingStatusBarVisibility != 0 ) {
3689- pw .print (prefix ); pw .print ("mLastSystemUiVisibility=0x" );
3690- pw .println (Integer .toHexString (mLastSystemUiVisibility ));
3691- pw .print (" mForceClearingStatusBarVisibility=0x" );
3692- pw .println (Integer .toHexString (mForceClearingStatusBarVisibility ));
3730+ if (mLastSystemUiFlags != 0 || mResettingSystemUiFlags != 0
3731+ || mForceClearedSystemUiFlags != 0 ) {
3732+ pw .print (prefix ); pw .print ("mLastSystemUiFlags=0x" );
3733+ pw .print (Integer .toHexString (mLastSystemUiFlags ));
3734+ pw .print (" mResettingSystemUiFlags=0x" );
3735+ pw .print (Integer .toHexString (mResettingSystemUiFlags ));
3736+ pw .print (" mForceClearedSystemUiFlags=0x" );
3737+ pw .println (Integer .toHexString (mForceClearedSystemUiFlags ));
36933738 }
36943739 pw .print (prefix ); pw .print ("mUiMode=" ); pw .print (mUiMode );
36953740 pw .print (" mDockMode=" ); pw .print (mDockMode );
0 commit comments