diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java index 6831eca32f726..df9a7c2cb5860 100644 --- a/core/java/android/inputmethodservice/InputMethodService.java +++ b/core/java/android/inputmethodservice/InputMethodService.java @@ -1700,8 +1700,12 @@ public class InputMethodService extends AbstractInputMethodService { if (config.orientation != Configuration.ORIENTATION_LANDSCAPE) { return false; } - if (mInputEditorInfo != null - && (mInputEditorInfo.imeOptions & EditorInfo.IME_FLAG_NO_FULLSCREEN) != 0) { + if ((mInputEditorInfo != null + && (mInputEditorInfo.imeOptions & EditorInfo.IME_FLAG_NO_FULLSCREEN) != 0) + // If app window has portrait orientation, regardless of what display orientation + // is, IME shouldn't use fullscreen-mode. + || (mInputEditorInfo.internalImeOptions + & EditorInfo.IME_FLAG_APP_WINDOW_PORTRAIT) != 0) { return false; } return true; diff --git a/core/java/android/view/inputmethod/EditorInfo.java b/core/java/android/view/inputmethod/EditorInfo.java index 7dbf693699964..1cf25a77fa38a 100644 --- a/core/java/android/view/inputmethod/EditorInfo.java +++ b/core/java/android/view/inputmethod/EditorInfo.java @@ -28,6 +28,7 @@ import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.RequiresPermission; +import android.content.res.Configuration; import android.os.Build.VERSION_CODES; import android.os.Bundle; import android.os.LocaleList; @@ -292,6 +293,13 @@ public class EditorInfo implements InputType, Parcelable { */ public static final int IME_FLAG_FORCE_ASCII = 0x80000000; + /** + * Flag of {@link #internalImeOptions}: flag is set when app window containing this + * {@link EditorInfo} is using {@link Configuration#ORIENTATION_PORTRAIT} mode. + * @hide + */ + public static final int IME_FLAG_APP_WINDOW_PORTRAIT = 0x80000000; + /** * Generic unspecified type for {@link #imeOptions}. */ @@ -312,6 +320,7 @@ public class EditorInfo implements InputType, Parcelable { * 1 1 IME_ACTION_NEXT * 11 IME_ACTION_DONE * 111 IME_ACTION_PREVIOUS + * 1 IME_FLAG_APP_WINDOW_PORTRAIT * 1 IME_FLAG_NO_PERSONALIZED_LEARNING * 1 IME_FLAG_NO_FULLSCREEN * 1 IME_FLAG_NAVIGATE_PREVIOUS @@ -342,6 +351,20 @@ public class EditorInfo implements InputType, Parcelable { */ public String privateImeOptions = null; + /** + * Masks for {@link internalImeOptions} + * + *
+ * 1 IME_FLAG_APP_WINDOW_PORTRAIT + * |-------|-------|-------|-------|+ */ + + /** + * Same as {@link android.R.attr#imeOptions} but for framework's internal-use only. + * @hide + */ + public int internalImeOptions = IME_NULL; + /** * In some cases an IME may be able to display an arbitrary label for * a command the user can perform, which you can specify here. This is diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java index 12c91fac0c65a..977a0e89a143d 100644 --- a/core/java/android/widget/TextView.java +++ b/core/java/android/widget/TextView.java @@ -17,6 +17,7 @@ package android.widget; import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; +import static android.content.res.Configuration.ORIENTATION_PORTRAIT; import static android.view.ContentInfo.FLAG_CONVERT_TO_PLAIN_TEXT; import static android.view.ContentInfo.SOURCE_AUTOFILL; import static android.view.ContentInfo.SOURCE_CLIPBOARD; @@ -8738,6 +8739,9 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener outAttrs.imeOptions |= EditorInfo.IME_FLAG_NO_ENTER_ACTION; } } + if (getResources().getConfiguration().orientation == ORIENTATION_PORTRAIT) { + outAttrs.internalImeOptions |= EditorInfo.IME_FLAG_APP_WINDOW_PORTRAIT; + } if (isMultilineInputType(outAttrs.inputType)) { // Multi-line text editors should always show an enter key. outAttrs.imeOptions |= EditorInfo.IME_FLAG_NO_ENTER_ACTION; diff --git a/core/tests/coretests/src/android/widget/TextViewTest.java b/core/tests/coretests/src/android/widget/TextViewTest.java index 40ecf9a83981d..66fdfff990f8e 100644 --- a/core/tests/coretests/src/android/widget/TextViewTest.java +++ b/core/tests/coretests/src/android/widget/TextViewTest.java @@ -16,6 +16,9 @@ package android.widget; +import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE; +import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT; + import static junit.framework.Assert.assertEquals; import static junit.framework.Assert.assertFalse; import static junit.framework.Assert.assertNotNull; @@ -30,6 +33,7 @@ import android.text.GetChars; import android.text.Layout; import android.text.PrecomputedText; import android.view.View; +import android.view.inputmethod.EditorInfo; import android.widget.TextView.BufferType; import androidx.test.InstrumentationRegistry; @@ -254,6 +258,24 @@ public class TextViewTest { assertEquals("", mTextView.getTransformed().toString()); } + @Test + @UiThreadTest + public void testPortraitDoesntSupportFullscreenIme() { + mActivity.setRequestedOrientation(SCREEN_ORIENTATION_PORTRAIT); + mTextView = new NullSetTextTextView(mActivity); + mTextView.requestFocus(); + assertEquals("IME_FLAG_NO_FULLSCREEN should be set", + mTextView.getImeOptions(), + mTextView.getImeOptions() & EditorInfo.IME_FLAG_NO_FULLSCREEN); + + mTextView.clearFocus(); + mActivity.setRequestedOrientation(SCREEN_ORIENTATION_LANDSCAPE); + mTextView = new NullSetTextTextView(mActivity); + mTextView.requestFocus(); + assertEquals("IME_FLAG_NO_FULLSCREEN should not be set", + 0, mTextView.getImeOptions() & EditorInfo.IME_FLAG_NO_FULLSCREEN); + } + private String createLongText() { int size = 600 * 1000; final StringBuilder builder = new StringBuilder(size);