diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl index fd458663a13af..9d4af006258e2 100644 --- a/core/java/android/view/IWindowManager.aidl +++ b/core/java/android/view/IWindowManager.aidl @@ -274,4 +274,11 @@ interface IWindowManager * @return The magnification spec if such or null. */ MagnificationSpec getCompatibleMagnificationSpecForWindow(in IBinder windowToken); + + /** + * Sets the current touch exploration state. + * + * @param enabled Whether touch exploration is enabled. + */ + void setTouchExplorationEnabled(boolean enabled); } diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java index 79aec904e8dc6..c5a1b86c0635a 100644 --- a/core/java/android/view/WindowManagerPolicy.java +++ b/core/java/android/view/WindowManagerPolicy.java @@ -1186,4 +1186,11 @@ public interface WindowManagerPolicy { * @return True if the window is a top level one. */ public boolean isTopLevelWindow(int windowType); + + /** + * Sets the current touch exploration state. + * + * @param enabled Whether touch exploration is enabled. + */ + public void setTouchExplorationEnabled(boolean enabled); } diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java index dd4f3d1f9be36..3468425e3a13f 100644 --- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java +++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java @@ -293,6 +293,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { boolean mOrientationSensorEnabled = false; int mCurrentAppOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; boolean mHasSoftInput = false; + boolean mTouchExplorationEnabled = false; int mPointerLocationMode = 0; // guarded by mLock @@ -1073,14 +1074,6 @@ public class PhoneWindowManager implements WindowManagerPolicy { mHasNavigationBar = true; } - if (mHasNavigationBar) { - // The navigation bar is at the right in landscape; it seems always - // useful to hide it for showing a video. - mCanHideNavigationBar = true; - } else { - mCanHideNavigationBar = false; - } - // For demo purposes, allow the rotation of the HDMI display to be controlled. // By default, HDMI locks rotation to landscape. if ("portrait".equals(SystemProperties.get("persist.demo.hdmirotation"))) { @@ -1100,6 +1093,14 @@ public class PhoneWindowManager implements WindowManagerPolicy { !"true".equals(SystemProperties.get("config.override_forced_orient")); } + /** + * @return whether the navigation bar can be hidden, e.g. the device has a + * navigation bar and touch exploration is not enabled + */ + private boolean canHideNavigationBar() { + return mHasNavigationBar && !mTouchExplorationEnabled; + } + @Override public boolean isDefaultOrientationForced() { return mForceDefaultOrientation; @@ -2580,7 +2581,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { if ((fl & (FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR)) == (FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR)) { int availRight, availBottom; - if (mCanHideNavigationBar && + if (canHideNavigationBar() && (systemUiVisibility & View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION) != 0) { availRight = mUnrestrictedScreenLeft + mUnrestrictedScreenWidth; availBottom = mUnrestrictedScreenTop + mUnrestrictedScreenHeight; @@ -2697,6 +2698,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { boolean navTranslucent = (sysui & View.NAVIGATION_BAR_TRANSLUCENT) != 0; boolean transientAllowed = (sysui & View.SYSTEM_UI_FLAG_IMMERSIVE) != 0; navTranslucent &= !transientAllowed; // transient trumps translucent + navTranslucent &= isTranslucentNavigationAllowed(); // When the navigation bar isn't visible, we put up a fake // input window to catch all touch events. This way we can @@ -2717,7 +2719,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { // For purposes of positioning and showing the nav bar, if we have // decided that it can't be hidden (because of the screen aspect ratio), // then take that into account. - navVisible |= !mCanHideNavigationBar; + navVisible |= !canHideNavigationBar(); boolean updateSysUiVisibility = false; if (mNavigationBar != null) { @@ -3063,7 +3065,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { pf.right = df.right = of.right = mOverscanScreenLeft + mOverscanScreenWidth; pf.bottom = df.bottom = of.bottom = mOverscanScreenTop + mOverscanScreenHeight; - } else if (mCanHideNavigationBar + } else if (canHideNavigationBar() && (sysUiFl & View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION) != 0 && attrs.type >= WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW && attrs.type <= WindowManager.LayoutParams.LAST_SUB_WINDOW) { @@ -3201,7 +3203,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { = mOverscanScreenLeft + mOverscanScreenWidth; pf.bottom = df.bottom = of.bottom = cf.bottom = mOverscanScreenTop + mOverscanScreenHeight; - } else if (mCanHideNavigationBar + } else if (canHideNavigationBar() && (sysUiFl & View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION) != 0 && (attrs.type == TYPE_TOAST || (attrs.type >= WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW @@ -5088,6 +5090,10 @@ public class PhoneWindowManager implements WindowManagerPolicy { vis = (vis & ~flags) | (oldVis & flags); } + if (!isTranslucentNavigationAllowed()) { + vis &= ~View.NAVIGATION_BAR_TRANSLUCENT; + } + // update status bar boolean transientAllowed = (vis & View.SYSTEM_UI_FLAG_IMMERSIVE) != 0; @@ -5138,6 +5144,14 @@ public class PhoneWindowManager implements WindowManagerPolicy { && (vis & View.SYSTEM_UI_FLAG_IMMERSIVE) != 0; } + /** + * @return whether the navigation bar can be made translucent, e.g. touch + * exploration is not enabled + */ + private boolean isTranslucentNavigationAllowed() { + return !mTouchExplorationEnabled; + } + // Use this instead of checking config_showNavigationBar so that it can be consistently // overridden by qemu.hw.mainkeys in the emulator. @Override @@ -5180,6 +5194,11 @@ public class PhoneWindowManager implements WindowManagerPolicy { return true; } + @Override + public void setTouchExplorationEnabled(boolean enabled) { + mTouchExplorationEnabled = enabled; + } + @Override public boolean isTopLevelWindow(int windowType) { if (windowType >= WindowManager.LayoutParams.FIRST_SUB_WINDOW diff --git a/services/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/java/com/android/server/accessibility/AccessibilityManagerService.java index 83e69d6f355a1..ccac0d32ea7be 100644 --- a/services/java/com/android/server/accessibility/AccessibilityManagerService.java +++ b/services/java/com/android/server/accessibility/AccessibilityManagerService.java @@ -1419,6 +1419,11 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { Settings.Secure.TOUCH_EXPLORATION_ENABLED, enabled ? 1 : 0, userState.mUserId); } + try { + mWindowManagerService.setTouchExplorationEnabled(enabled); + } catch (RemoteException e) { + e.printStackTrace(); + } } private boolean canRequestAndRequestsTouchExplorationLocked(Service service) { diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java index 9bbaf603d313d..36b34f86ae0bb 100644 --- a/services/java/com/android/server/wm/WindowManagerService.java +++ b/services/java/com/android/server/wm/WindowManagerService.java @@ -5206,6 +5206,11 @@ public class WindowManagerService extends IWindowManager.Stub mInputManager.setInputFilter(filter); } + @Override + public void setTouchExplorationEnabled(boolean enabled) { + mPolicy.setTouchExplorationEnabled(enabled); + } + public void setCurrentUser(final int newUserId) { synchronized (mWindowMap) { int oldUserId = mCurrentUserId; diff --git a/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java b/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java index 225b0c3f4be9f..fd153af993535 100644 --- a/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java +++ b/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java @@ -494,4 +494,8 @@ public class IWindowManagerImpl implements IWindowManager { // TODO Auto-generated method stub return false; } + + @Override + public void setTouchExplorationEnabled(boolean enabled) { + } }