Merge "Ignore certain WindowManager flags when touch exploration is enabled" into klp-dev
diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl
index fd45866..9d4af00 100644
--- a/core/java/android/view/IWindowManager.aidl
+++ b/core/java/android/view/IWindowManager.aidl
@@ -274,4 +274,11 @@
      * @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 79aec90..c5a1b86c 100644
--- a/core/java/android/view/WindowManagerPolicy.java
+++ b/core/java/android/view/WindowManagerPolicy.java
@@ -1186,4 +1186,11 @@
      * @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 dd4f3d1..3468425 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 @@
     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 @@
             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 @@
                 !"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 @@
         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 @@
             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 @@
             // 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 @@
                         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 @@
                             = 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 @@
             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 @@
                 && (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
@@ -5181,6 +5195,11 @@
     }
 
     @Override
+    public void setTouchExplorationEnabled(boolean enabled) {
+        mTouchExplorationEnabled = enabled;
+    }
+
+    @Override
     public boolean isTopLevelWindow(int windowType) {
         if (windowType >= WindowManager.LayoutParams.FIRST_SUB_WINDOW
                 && windowType <= WindowManager.LayoutParams.LAST_SUB_WINDOW) {
diff --git a/services/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/java/com/android/server/accessibility/AccessibilityManagerService.java
index 83e69d6f..ccac0d3 100644
--- a/services/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -1419,6 +1419,11 @@
                     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 0e0d098..e089ca6 100644
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -5206,6 +5206,11 @@
         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 225b0c3..fd153af 100644
--- a/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java
+++ b/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java
@@ -494,4 +494,8 @@
         // TODO Auto-generated method stub
         return false;
     }
+
+    @Override
+    public void setTouchExplorationEnabled(boolean enabled) {
+    }
 }