Loading core/java/android/inputmethodservice/InputMethodService.java +6 −0 Original line number Diff line number Diff line Loading @@ -576,6 +576,12 @@ public class InputMethodService extends AbstractInputMethodService { @EnabledSince(targetSdkVersion = Build.VERSION_CODES.UPSIDE_DOWN_CAKE) public static final long DISALLOW_INPUT_METHOD_INTERFACE_OVERRIDE = 148086656L; /** * Enable the logic to allow hiding the IME caption bar ("fake" IME navigation bar). * @hide */ public static final boolean ENABLE_HIDE_IME_CAPTION_BAR = false; LayoutInflater mInflater; TypedArray mThemeAttrs; @UnsupportedAppUsage Loading core/java/android/inputmethodservice/NavigationBarController.java +33 −1 Original line number Diff line number Diff line Loading @@ -16,6 +16,8 @@ package android.inputmethodservice; import static android.inputmethodservice.InputMethodService.ENABLE_HIDE_IME_CAPTION_BAR; import static android.view.WindowInsets.Type.captionBar; import static android.view.WindowInsetsController.APPEARANCE_LIGHT_NAVIGATION_BARS; import android.animation.ValueAnimator; Loading Loading @@ -230,6 +232,16 @@ final class NavigationBarController { setIconTintInternal(calculateTargetDarkIntensity(mAppearance, mDrawLegacyNavigationBarBackground)); if (ENABLE_HIDE_IME_CAPTION_BAR) { mNavigationBarFrame.setOnApplyWindowInsetsListener((view, insets) -> { if (mNavigationBarFrame != null) { boolean visible = insets.isVisible(captionBar()); mNavigationBarFrame.setVisibility(visible ? View.VISIBLE : View.INVISIBLE); } return view.onApplyWindowInsets(insets); }); } } private void uninstallNavigationBarFrameIfNecessary() { Loading @@ -240,6 +252,9 @@ final class NavigationBarController { if (parent instanceof ViewGroup) { ((ViewGroup) parent).removeView(mNavigationBarFrame); } if (ENABLE_HIDE_IME_CAPTION_BAR) { mNavigationBarFrame.setOnApplyWindowInsetsListener(null); } mNavigationBarFrame = null; } Loading Loading @@ -414,9 +429,11 @@ final class NavigationBarController { decor.bringChildToFront(mNavigationBarFrame); } } if (!ENABLE_HIDE_IME_CAPTION_BAR) { mNavigationBarFrame.setVisibility(View.VISIBLE); } } } @Override public void onNavButtonFlagsChanged(@InputMethodNavButtonFlags int navButtonFlags) { Loading @@ -435,6 +452,11 @@ final class NavigationBarController { mShouldShowImeSwitcherWhenImeIsShown; mShouldShowImeSwitcherWhenImeIsShown = shouldShowImeSwitcherWhenImeIsShown; if (ENABLE_HIDE_IME_CAPTION_BAR) { mService.mWindow.getWindow().getDecorView().getWindowInsetsController() .setImeCaptionBarInsetsHeight(getImeCaptionBarHeight()); } if (imeDrawsImeNavBar) { installNavigationBarFrameIfNecessary(); if (mNavigationBarFrame == null) { Loading Loading @@ -528,6 +550,16 @@ final class NavigationBarController { return drawLegacyNavigationBarBackground; } /** * Returns the height of the IME caption bar if this should be shown, or {@code 0} instead. */ private int getImeCaptionBarHeight() { return mImeDrawsImeNavBar ? mService.getResources().getDimensionPixelSize( com.android.internal.R.dimen.navigation_bar_frame_height) : 0; } @Override public String toDebugString() { return "{mImeDrawsImeNavBar=" + mImeDrawsImeNavBar Loading core/java/android/view/InsetsController.java +47 −1 Original line number Diff line number Diff line Loading @@ -16,10 +16,12 @@ package android.view; import static android.inputmethodservice.InputMethodService.ENABLE_HIDE_IME_CAPTION_BAR; import static android.os.Trace.TRACE_TAG_VIEW; import static android.view.InsetsControllerProto.CONTROL; import static android.view.InsetsControllerProto.STATE; import static android.view.InsetsSource.ID_IME; import static android.view.InsetsSource.ID_IME_CAPTION_BAR; import static android.view.ViewRootImpl.CAPTION_ON_SHELL; import static android.view.WindowInsets.Type.FIRST; import static android.view.WindowInsets.Type.LAST; Loading @@ -40,6 +42,7 @@ import android.app.ActivityThread; import android.content.Context; import android.content.res.CompatibilityInfo; import android.graphics.Insets; import android.graphics.Point; import android.graphics.Rect; import android.os.CancellationSignal; import android.os.Handler; Loading Loading @@ -652,6 +655,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation private int mLastWindowingMode; private boolean mStartingAnimation; private int mCaptionInsetsHeight = 0; private int mImeCaptionBarInsetsHeight = 0; private boolean mAnimationsDisabled; private boolean mCompatSysUiVisibilityStaled; Loading Loading @@ -693,6 +697,9 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation if (!CAPTION_ON_SHELL && source1.getType() == captionBar()) { return; } if (source1.getId() == ID_IME_CAPTION_BAR) { return; } // Don't change the indexes of the sources while traversing. Remove it later. mPendingRemoveIndexes.add(index1); Loading Loading @@ -823,6 +830,9 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation if (mFrame.equals(frame)) { return; } if (mImeCaptionBarInsetsHeight != 0) { setImeCaptionBarInsetsHeight(mImeCaptionBarInsetsHeight); } mHost.notifyInsetsChanged(); mFrame.set(frame); } Loading Loading @@ -1007,6 +1017,12 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation // Ensure to update all existing source consumers for (int i = mSourceConsumers.size() - 1; i >= 0; i--) { final InsetsSourceConsumer consumer = mSourceConsumers.valueAt(i); if (consumer.getId() == ID_IME_CAPTION_BAR) { // The inset control for the IME caption bar will never be dispatched // by the server. continue; } final InsetsSourceControl control = mTmpControlArray.get(consumer.getId()); if (control != null) { controllableTypes |= control.getType(); Loading Loading @@ -1499,7 +1515,8 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation continue; } final InsetsSourceControl control = consumer.getControl(); if (control != null && control.getLeash() != null) { if (control != null && (control.getLeash() != null || control.getId() == ID_IME_CAPTION_BAR)) { controls.put(control.getId(), new InsetsSourceControl(control)); typesReady |= consumer.getType(); } Loading Loading @@ -1884,6 +1901,35 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation } } @Override public void setImeCaptionBarInsetsHeight(int height) { if (!ENABLE_HIDE_IME_CAPTION_BAR) { return; } Rect newFrame = new Rect(mFrame.left, mFrame.bottom - height, mFrame.right, mFrame.bottom); InsetsSource source = mState.peekSource(ID_IME_CAPTION_BAR); if (mImeCaptionBarInsetsHeight != height || (source != null && !newFrame.equals(source.getFrame()))) { mImeCaptionBarInsetsHeight = height; if (mImeCaptionBarInsetsHeight != 0) { mState.getOrCreateSource(ID_IME_CAPTION_BAR, captionBar()) .setFrame(newFrame); getSourceConsumer(ID_IME_CAPTION_BAR, captionBar()).setControl( new InsetsSourceControl(ID_IME_CAPTION_BAR, captionBar(), null /* leash */, false /* initialVisible */, new Point(), Insets.NONE), new int[1], new int[1]); } else { mState.removeSource(ID_IME_CAPTION_BAR); InsetsSourceConsumer sourceConsumer = mSourceConsumers.get(ID_IME_CAPTION_BAR); if (sourceConsumer != null) { sourceConsumer.setControl(null, new int[1], new int[1]); } } mHost.notifyInsetsChanged(); } } @Override public void setSystemBarsBehavior(@Behavior int behavior) { mHost.setSystemBarsBehavior(behavior); Loading core/java/android/view/InsetsSource.java +7 −1 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ import static android.view.InsetsSourceProto.FRAME; import static android.view.InsetsSourceProto.TYPE; import static android.view.InsetsSourceProto.VISIBLE; import static android.view.InsetsSourceProto.VISIBLE_FRAME; import static android.view.WindowInsets.Type.captionBar; import static android.view.WindowInsets.Type.ime; import android.annotation.IntDef; Loading Loading @@ -47,6 +48,9 @@ public class InsetsSource implements Parcelable { /** The insets source ID of IME */ public static final int ID_IME = createId(null, 0, ime()); /** The insets source ID of the IME caption bar ("fake" IME navigation bar). */ static final int ID_IME_CAPTION_BAR = InsetsSource.createId(null /* owner */, 1 /* index */, captionBar()); /** * Controls whether this source suppresses the scrim. If the scrim is ignored, the system won't Loading Loading @@ -215,7 +219,9 @@ public class InsetsSource implements Parcelable { // During drag-move and drag-resizing, the caption insets position may not get updated // before the app frame get updated. To layout the app content correctly during drag events, // we always return the insets with the corresponding height covering the top. if (getType() == WindowInsets.Type.captionBar()) { // However, with the "fake" IME navigation bar treated as a caption bar, we skip this case // to set the actual insets towards the bottom of the screen. if (getType() == WindowInsets.Type.captionBar() && getId() != ID_IME_CAPTION_BAR) { return Insets.of(0, frame.height(), 0, 0); } // Checks for whether there is shared edge with insets for 0-width/height window. Loading core/java/android/view/PendingInsetsController.java +9 −0 Original line number Diff line number Diff line Loading @@ -44,6 +44,7 @@ public class PendingInsetsController implements WindowInsetsController { private ArrayList<OnControllableInsetsChangedListener> mControllableInsetsChangedListeners = new ArrayList<>(); private int mCaptionInsetsHeight = 0; private int mImeCaptionBarInsetsHeight = 0; private WindowInsetsAnimationControlListener mLoggingListener; private @InsetsType int mRequestedVisibleTypes = WindowInsets.Type.defaultVisible(); Loading Loading @@ -90,6 +91,11 @@ public class PendingInsetsController implements WindowInsetsController { mCaptionInsetsHeight = height; } @Override public void setImeCaptionBarInsetsHeight(int height) { mImeCaptionBarInsetsHeight = height; } @Override public void setSystemBarsBehavior(int behavior) { if (mReplayedInsetsController != null) { Loading Loading @@ -168,6 +174,9 @@ public class PendingInsetsController implements WindowInsetsController { if (mCaptionInsetsHeight != 0) { controller.setCaptionInsetsHeight(mCaptionInsetsHeight); } if (mImeCaptionBarInsetsHeight != 0) { controller.setImeCaptionBarInsetsHeight(mImeCaptionBarInsetsHeight); } if (mAnimationsDisabled) { controller.setAnimationsDisabled(true); } Loading Loading
core/java/android/inputmethodservice/InputMethodService.java +6 −0 Original line number Diff line number Diff line Loading @@ -576,6 +576,12 @@ public class InputMethodService extends AbstractInputMethodService { @EnabledSince(targetSdkVersion = Build.VERSION_CODES.UPSIDE_DOWN_CAKE) public static final long DISALLOW_INPUT_METHOD_INTERFACE_OVERRIDE = 148086656L; /** * Enable the logic to allow hiding the IME caption bar ("fake" IME navigation bar). * @hide */ public static final boolean ENABLE_HIDE_IME_CAPTION_BAR = false; LayoutInflater mInflater; TypedArray mThemeAttrs; @UnsupportedAppUsage Loading
core/java/android/inputmethodservice/NavigationBarController.java +33 −1 Original line number Diff line number Diff line Loading @@ -16,6 +16,8 @@ package android.inputmethodservice; import static android.inputmethodservice.InputMethodService.ENABLE_HIDE_IME_CAPTION_BAR; import static android.view.WindowInsets.Type.captionBar; import static android.view.WindowInsetsController.APPEARANCE_LIGHT_NAVIGATION_BARS; import android.animation.ValueAnimator; Loading Loading @@ -230,6 +232,16 @@ final class NavigationBarController { setIconTintInternal(calculateTargetDarkIntensity(mAppearance, mDrawLegacyNavigationBarBackground)); if (ENABLE_HIDE_IME_CAPTION_BAR) { mNavigationBarFrame.setOnApplyWindowInsetsListener((view, insets) -> { if (mNavigationBarFrame != null) { boolean visible = insets.isVisible(captionBar()); mNavigationBarFrame.setVisibility(visible ? View.VISIBLE : View.INVISIBLE); } return view.onApplyWindowInsets(insets); }); } } private void uninstallNavigationBarFrameIfNecessary() { Loading @@ -240,6 +252,9 @@ final class NavigationBarController { if (parent instanceof ViewGroup) { ((ViewGroup) parent).removeView(mNavigationBarFrame); } if (ENABLE_HIDE_IME_CAPTION_BAR) { mNavigationBarFrame.setOnApplyWindowInsetsListener(null); } mNavigationBarFrame = null; } Loading Loading @@ -414,9 +429,11 @@ final class NavigationBarController { decor.bringChildToFront(mNavigationBarFrame); } } if (!ENABLE_HIDE_IME_CAPTION_BAR) { mNavigationBarFrame.setVisibility(View.VISIBLE); } } } @Override public void onNavButtonFlagsChanged(@InputMethodNavButtonFlags int navButtonFlags) { Loading @@ -435,6 +452,11 @@ final class NavigationBarController { mShouldShowImeSwitcherWhenImeIsShown; mShouldShowImeSwitcherWhenImeIsShown = shouldShowImeSwitcherWhenImeIsShown; if (ENABLE_HIDE_IME_CAPTION_BAR) { mService.mWindow.getWindow().getDecorView().getWindowInsetsController() .setImeCaptionBarInsetsHeight(getImeCaptionBarHeight()); } if (imeDrawsImeNavBar) { installNavigationBarFrameIfNecessary(); if (mNavigationBarFrame == null) { Loading Loading @@ -528,6 +550,16 @@ final class NavigationBarController { return drawLegacyNavigationBarBackground; } /** * Returns the height of the IME caption bar if this should be shown, or {@code 0} instead. */ private int getImeCaptionBarHeight() { return mImeDrawsImeNavBar ? mService.getResources().getDimensionPixelSize( com.android.internal.R.dimen.navigation_bar_frame_height) : 0; } @Override public String toDebugString() { return "{mImeDrawsImeNavBar=" + mImeDrawsImeNavBar Loading
core/java/android/view/InsetsController.java +47 −1 Original line number Diff line number Diff line Loading @@ -16,10 +16,12 @@ package android.view; import static android.inputmethodservice.InputMethodService.ENABLE_HIDE_IME_CAPTION_BAR; import static android.os.Trace.TRACE_TAG_VIEW; import static android.view.InsetsControllerProto.CONTROL; import static android.view.InsetsControllerProto.STATE; import static android.view.InsetsSource.ID_IME; import static android.view.InsetsSource.ID_IME_CAPTION_BAR; import static android.view.ViewRootImpl.CAPTION_ON_SHELL; import static android.view.WindowInsets.Type.FIRST; import static android.view.WindowInsets.Type.LAST; Loading @@ -40,6 +42,7 @@ import android.app.ActivityThread; import android.content.Context; import android.content.res.CompatibilityInfo; import android.graphics.Insets; import android.graphics.Point; import android.graphics.Rect; import android.os.CancellationSignal; import android.os.Handler; Loading Loading @@ -652,6 +655,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation private int mLastWindowingMode; private boolean mStartingAnimation; private int mCaptionInsetsHeight = 0; private int mImeCaptionBarInsetsHeight = 0; private boolean mAnimationsDisabled; private boolean mCompatSysUiVisibilityStaled; Loading Loading @@ -693,6 +697,9 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation if (!CAPTION_ON_SHELL && source1.getType() == captionBar()) { return; } if (source1.getId() == ID_IME_CAPTION_BAR) { return; } // Don't change the indexes of the sources while traversing. Remove it later. mPendingRemoveIndexes.add(index1); Loading Loading @@ -823,6 +830,9 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation if (mFrame.equals(frame)) { return; } if (mImeCaptionBarInsetsHeight != 0) { setImeCaptionBarInsetsHeight(mImeCaptionBarInsetsHeight); } mHost.notifyInsetsChanged(); mFrame.set(frame); } Loading Loading @@ -1007,6 +1017,12 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation // Ensure to update all existing source consumers for (int i = mSourceConsumers.size() - 1; i >= 0; i--) { final InsetsSourceConsumer consumer = mSourceConsumers.valueAt(i); if (consumer.getId() == ID_IME_CAPTION_BAR) { // The inset control for the IME caption bar will never be dispatched // by the server. continue; } final InsetsSourceControl control = mTmpControlArray.get(consumer.getId()); if (control != null) { controllableTypes |= control.getType(); Loading Loading @@ -1499,7 +1515,8 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation continue; } final InsetsSourceControl control = consumer.getControl(); if (control != null && control.getLeash() != null) { if (control != null && (control.getLeash() != null || control.getId() == ID_IME_CAPTION_BAR)) { controls.put(control.getId(), new InsetsSourceControl(control)); typesReady |= consumer.getType(); } Loading Loading @@ -1884,6 +1901,35 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation } } @Override public void setImeCaptionBarInsetsHeight(int height) { if (!ENABLE_HIDE_IME_CAPTION_BAR) { return; } Rect newFrame = new Rect(mFrame.left, mFrame.bottom - height, mFrame.right, mFrame.bottom); InsetsSource source = mState.peekSource(ID_IME_CAPTION_BAR); if (mImeCaptionBarInsetsHeight != height || (source != null && !newFrame.equals(source.getFrame()))) { mImeCaptionBarInsetsHeight = height; if (mImeCaptionBarInsetsHeight != 0) { mState.getOrCreateSource(ID_IME_CAPTION_BAR, captionBar()) .setFrame(newFrame); getSourceConsumer(ID_IME_CAPTION_BAR, captionBar()).setControl( new InsetsSourceControl(ID_IME_CAPTION_BAR, captionBar(), null /* leash */, false /* initialVisible */, new Point(), Insets.NONE), new int[1], new int[1]); } else { mState.removeSource(ID_IME_CAPTION_BAR); InsetsSourceConsumer sourceConsumer = mSourceConsumers.get(ID_IME_CAPTION_BAR); if (sourceConsumer != null) { sourceConsumer.setControl(null, new int[1], new int[1]); } } mHost.notifyInsetsChanged(); } } @Override public void setSystemBarsBehavior(@Behavior int behavior) { mHost.setSystemBarsBehavior(behavior); Loading
core/java/android/view/InsetsSource.java +7 −1 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ import static android.view.InsetsSourceProto.FRAME; import static android.view.InsetsSourceProto.TYPE; import static android.view.InsetsSourceProto.VISIBLE; import static android.view.InsetsSourceProto.VISIBLE_FRAME; import static android.view.WindowInsets.Type.captionBar; import static android.view.WindowInsets.Type.ime; import android.annotation.IntDef; Loading Loading @@ -47,6 +48,9 @@ public class InsetsSource implements Parcelable { /** The insets source ID of IME */ public static final int ID_IME = createId(null, 0, ime()); /** The insets source ID of the IME caption bar ("fake" IME navigation bar). */ static final int ID_IME_CAPTION_BAR = InsetsSource.createId(null /* owner */, 1 /* index */, captionBar()); /** * Controls whether this source suppresses the scrim. If the scrim is ignored, the system won't Loading Loading @@ -215,7 +219,9 @@ public class InsetsSource implements Parcelable { // During drag-move and drag-resizing, the caption insets position may not get updated // before the app frame get updated. To layout the app content correctly during drag events, // we always return the insets with the corresponding height covering the top. if (getType() == WindowInsets.Type.captionBar()) { // However, with the "fake" IME navigation bar treated as a caption bar, we skip this case // to set the actual insets towards the bottom of the screen. if (getType() == WindowInsets.Type.captionBar() && getId() != ID_IME_CAPTION_BAR) { return Insets.of(0, frame.height(), 0, 0); } // Checks for whether there is shared edge with insets for 0-width/height window. Loading
core/java/android/view/PendingInsetsController.java +9 −0 Original line number Diff line number Diff line Loading @@ -44,6 +44,7 @@ public class PendingInsetsController implements WindowInsetsController { private ArrayList<OnControllableInsetsChangedListener> mControllableInsetsChangedListeners = new ArrayList<>(); private int mCaptionInsetsHeight = 0; private int mImeCaptionBarInsetsHeight = 0; private WindowInsetsAnimationControlListener mLoggingListener; private @InsetsType int mRequestedVisibleTypes = WindowInsets.Type.defaultVisible(); Loading Loading @@ -90,6 +91,11 @@ public class PendingInsetsController implements WindowInsetsController { mCaptionInsetsHeight = height; } @Override public void setImeCaptionBarInsetsHeight(int height) { mImeCaptionBarInsetsHeight = height; } @Override public void setSystemBarsBehavior(int behavior) { if (mReplayedInsetsController != null) { Loading Loading @@ -168,6 +174,9 @@ public class PendingInsetsController implements WindowInsetsController { if (mCaptionInsetsHeight != 0) { controller.setCaptionInsetsHeight(mCaptionInsetsHeight); } if (mImeCaptionBarInsetsHeight != 0) { controller.setImeCaptionBarInsetsHeight(mImeCaptionBarInsetsHeight); } if (mAnimationsDisabled) { controller.setAnimationsDisabled(true); } Loading