Skip to content

Commit cd8640f

Browse files
Dianne HackbornAndroid (Google) Code Review
authored andcommitted
Merge "Fix issue #5398675: It's (too) easy to keep the navigation bar..." into ics-mr0
2 parents 7b5dd87 + e26ab70 commit cd8640f

File tree

1 file changed

+77
-32
lines changed

1 file changed

+77
-32
lines changed

policy/src/com/android/internal/policy/impl/PhoneWindowManager.java

Lines changed: 77 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)