diff options
| -rw-r--r-- | core/java/android/inputmethodservice/SoftInputWindow.java | 13 | ||||
| -rw-r--r-- | core/res/res/values/config.xml | 5 | ||||
| -rw-r--r-- | core/res/res/values/symbols.xml | 2 | ||||
| -rw-r--r-- | packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java | 93 |
4 files changed, 98 insertions, 15 deletions
diff --git a/core/java/android/inputmethodservice/SoftInputWindow.java b/core/java/android/inputmethodservice/SoftInputWindow.java index 0513feef801f..356b3448430a 100644 --- a/core/java/android/inputmethodservice/SoftInputWindow.java +++ b/core/java/android/inputmethodservice/SoftInputWindow.java @@ -21,6 +21,7 @@ import static java.lang.annotation.RetentionPolicy.SOURCE; import android.annotation.IntDef; import android.app.Dialog; import android.content.Context; +import android.content.pm.PackageManager; import android.graphics.Rect; import android.os.Debug; import android.os.IBinder; @@ -50,6 +51,7 @@ public class SoftInputWindow extends Dialog { final int mWindowType; final int mGravity; final boolean mTakesFocus; + final boolean mAutomotiveHideNavBarForKeyboard; private final Rect mBounds = new Rect(); @Retention(SOURCE) @@ -134,6 +136,8 @@ public class SoftInputWindow extends Dialog { mWindowType = windowType; mGravity = gravity; mTakesFocus = takesFocus; + mAutomotiveHideNavBarForKeyboard = context.getResources().getBoolean( + com.android.internal.R.bool.config_automotiveHideNavBarForKeyboard); initDockWindow(); } @@ -247,6 +251,11 @@ public class SoftInputWindow extends Dialog { windowModFlags |= WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL; } + if (isAutomotive() && mAutomotiveHideNavBarForKeyboard) { + windowSetFlags |= WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS; + windowModFlags |= WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS; + } + getWindow().setFlags(windowSetFlags, windowModFlags); } @@ -338,6 +347,10 @@ public class SoftInputWindow extends Dialog { mWindowState = newState; } + private boolean isAutomotive() { + return getContext().getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE); + } + private static String stateToString(@SoftInputWindowState int state) { switch (state) { case SoftInputWindowState.TOKEN_PENDING: diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index 40c2cbedc73d..ceccd0dcdfec 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -4286,4 +4286,9 @@ <!-- The list of packages to automatically opt out of refresh rates higher than 60hz because of known compatibility issues. --> <string-array name="config_highRefreshRateBlacklist"></string-array> + + <!-- Whether or not to hide the navigation bar when the soft keyboard is visible in order to + create additional screen real estate outside beyond the keyboard. Note that the user needs + to have a confirmed way to dismiss the keyboard when desired. --> + <bool name="config_automotiveHideNavBarForKeyboard">false</bool> </resources> diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index f7ae453599bb..ae5fd83f38e0 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -3847,4 +3847,6 @@ <java-symbol type="string" name="config_factoryResetPackage" /> <java-symbol type="array" name="config_highRefreshRateBlacklist" /> + <java-symbol type="bool" name="config_automotiveHideNavBarForKeyboard" /> + </resources> diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java index 97fbea6ea237..e95103bcb929 100644 --- a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java +++ b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java @@ -32,7 +32,10 @@ import android.content.res.Configuration; import android.graphics.PixelFormat; import android.graphics.Rect; import android.graphics.drawable.Drawable; +import android.inputmethodservice.InputMethodService; +import android.os.IBinder; import android.util.Log; +import android.view.Display; import android.view.GestureDetector; import android.view.Gravity; import android.view.MotionEvent; @@ -87,8 +90,7 @@ import java.util.Map; /** * A status bar (and navigation bar) tailored for the automotive use case. */ -public class CarStatusBar extends StatusBar implements - CarBatteryController.BatteryViewHandler { +public class CarStatusBar extends StatusBar implements CarBatteryController.BatteryViewHandler { private static final String TAG = "CarStatusBar"; // used to calculate how fast to open or close the window private static final float DEFAULT_FLING_VELOCITY = 0; @@ -169,6 +171,9 @@ public class CarStatusBar extends StatusBar implements private boolean mIsSwipingVerticallyToClose; // Whether heads-up notifications should be shown when shade is open. private boolean mEnableHeadsUpNotificationWhenNotificationShadeOpen; + // If the nav bar should be hidden when the soft keyboard is visible. + private boolean mHideNavBarForKeyboard; + private boolean mBottomNavBarVisible; private final CarPowerStateListener mCarPowerStateListener = (int state) -> { @@ -190,6 +195,12 @@ public class CarStatusBar extends StatusBar implements // builds the nav bar mDeviceProvisionedController = Dependency.get(DeviceProvisionedController.class); mDeviceIsProvisioned = mDeviceProvisionedController.isDeviceProvisioned(); + + // Keyboard related setup, before nav bars are created. + mHideNavBarForKeyboard = mContext.getResources().getBoolean( + com.android.internal.R.bool.config_automotiveHideNavBarForKeyboard); + mBottomNavBarVisible = false; + super.start(); mTaskStackListener = new TaskStackListenerImpl(); mActivityManagerWrapper = ActivityManagerWrapper.getInstance(); @@ -720,6 +731,13 @@ public class CarStatusBar extends StatusBar implements buildNavBarContent(); attachNavBarWindows(); + // Try setting up the initial state of the nav bar if applicable. + if (result != null) { + setImeWindowStatus(Display.DEFAULT_DISPLAY, result.mImeToken, + result.mImeWindowVis, result.mImeBackDisposition, + result.mShowImeSwitcher); + } + // There has been a car customized nav bar on the default display, so just create nav bars // on external displays. mNavigationBarController.createNavigationBars(false /* includeDefaultDisplay */, result); @@ -758,21 +776,32 @@ public class CarStatusBar extends StatusBar implements } - private void attachNavBarWindows() { + /** + * We register for soft keyboard visibility events such that we can hide the navigation bar + * giving more screen space to the IME. Note: this is optional and controlled by + * {@code com.android.internal.R.bool.config_automotiveHideNavBarForKeyboard}. + */ + @Override + public void setImeWindowStatus(int displayId, IBinder token, int vis, int backDisposition, + boolean showImeSwitcher) { + if (!mHideNavBarForKeyboard) { + return; + } - if (mShowBottom) { - WindowManager.LayoutParams lp = new WindowManager.LayoutParams( - LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT, - WindowManager.LayoutParams.TYPE_NAVIGATION_BAR, - WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE - | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL - | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH - | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH, - PixelFormat.TRANSLUCENT); - lp.setTitle("CarNavigationBar"); - lp.windowAnimations = 0; - mWindowManager.addView(mNavigationBarWindow, lp); + if (mContext.getDisplay().getDisplayId() != displayId) { + return; + } + + boolean isKeyboardVisible = (vis & InputMethodService.IME_VISIBLE) != 0; + if (!isKeyboardVisible) { + attachBottomNavBarWindow(); + } else { + detachBottomNavBarWindow(); } + } + + private void attachNavBarWindows() { + attachBottomNavBarWindow(); if (mShowLeft) { int width = mContext.getResources().getDimensionPixelSize( @@ -808,7 +837,41 @@ public class CarStatusBar extends StatusBar implements rightlp.gravity = Gravity.RIGHT; mWindowManager.addView(mRightNavigationBarWindow, rightlp); } + } + + private void attachBottomNavBarWindow() { + if (!mShowBottom) { + return; + } + if (mBottomNavBarVisible) { + return; + } + mBottomNavBarVisible = true; + + WindowManager.LayoutParams lp = new WindowManager.LayoutParams( + LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT, + WindowManager.LayoutParams.TYPE_NAVIGATION_BAR, + WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE + | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL + | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH + | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH, + PixelFormat.TRANSLUCENT); + lp.setTitle("CarNavigationBar"); + lp.windowAnimations = 0; + mWindowManager.addView(mNavigationBarWindow, lp); + } + + private void detachBottomNavBarWindow() { + if (!mShowBottom) { + return; + } + + if (!mBottomNavBarVisible) { + return; + } + mBottomNavBarVisible = false; + mWindowManager.removeView(mNavigationBarWindow); } private void buildBottomBar(int layout) { |