Using IME context to inflate layout from S_V2

With CL[1],[2] to migrate InputMethodService as the subclass of the new
introduced class WindowProviderService in S_V2, IME context resources
can be managed by associating the window container of IME window when
its display/window configuration changed.

So we can get rid of createDisplayContext logic from S_V2 with gated
by SDK version and refining the method of get IME context with
documentation to make it clear.

[1]: Ie565e30ed5dd3f2cfe27355a6dded76dc3adc14b
[2]: I64a1614f32d097785915f6105b1813a929e0fe32

Bug: 213118079
Bug: 133825283
Test: manual with below steps
 1) adb install -r EditTextVariations.apk
 2) tapas LatinIME
 3) make
 4) adb install -r out/target/product/generic/system/app/LatinIME/\
        LatinIME.apk
 5) adb shell ime enable com.android.inputmethod.latin/.LatinIME
 6) adb shell ime set com.android.inputmethod.latin/.LatinIME
 5) Enable screen auto-rotation
 7) Launch EditTextVariations from launcher's shortcut
 8) Tap the first EditText field to show IME
 9) Rotate the device to the landscape mode
 10) Expect the IME should not be shrunk

Change-Id: If2cc1c5bdb257a9c0af653fa7157cf781a90bf1d
main
Ming-Shin Lu 2022-01-12 00:17:27 +08:00
parent 7f3bcefd9f
commit 6c752d8eca
1 changed files with 37 additions and 19 deletions

View File

@ -16,8 +16,6 @@
package com.android.inputmethod.latin;
import static android.view.Display.INVALID_DISPLAY;
import static com.android.inputmethod.latin.common.Constants.ImeOption.FORCE_ASCII;
import static com.android.inputmethod.latin.common.Constants.ImeOption.NO_MICROPHONE;
import static com.android.inputmethod.latin.common.Constants.ImeOption.NO_MICROPHONE_COMPAT;
@ -46,6 +44,7 @@ import android.util.Log;
import android.util.PrintWriterPrinter;
import android.util.Printer;
import android.util.SparseArray;
import android.view.Display;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.View;
@ -56,12 +55,13 @@ import android.view.inputmethod.CompletionInfo;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputMethodSubtype;
import androidx.annotation.NonNull;
import com.android.inputmethod.accessibility.AccessibilityUtils;
import com.android.inputmethod.annotations.UsedForTesting;
import com.android.inputmethod.compat.BuildCompatUtils;
import com.android.inputmethod.compat.EditorInfoCompatUtils;
import com.android.inputmethod.compat.InputMethodServiceCompatUtils;
import com.android.inputmethod.compat.InputMethodSubtypeCompatUtils;
import com.android.inputmethod.compat.ViewOutlineProviderCompatUtils;
import com.android.inputmethod.compat.ViewOutlineProviderCompatUtils.InsetsUpdater;
import com.android.inputmethod.dictionarypack.DictionaryPackConstants;
@ -170,7 +170,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
// Used for re-initialize keyboard layout after onConfigurationChange.
@Nullable private Context mDisplayContext;
private int mCurDisplayId = INVALID_DISPLAY;
// Object for reacting to adding/removing a dictionary pack.
private final BroadcastReceiver mDictionaryPackInstallReceiver =
@ -604,8 +603,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
AccessibilityUtils.init(this);
mStatsUtilsManager.onCreate(this /* context */, mDictionaryFacilitator);
final WindowManager wm = getSystemService(WindowManager.class);
mDisplayContext = createDisplayContext(wm.getDefaultDisplay());
mCurDisplayId = wm.getDefaultDisplay().getDisplayId();
mDisplayContext = getDisplayContext();
KeyboardSwitcher.init(this);
super.onCreate();
@ -795,20 +793,40 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
@Override
public void onInitializeInterface() {
// TODO (b/133825283): Non-activity components Resources / DisplayMetrics update when
// moving to external display.
// An issue in Q that non-activity components Resources / DisplayMetrics in
// Context doesn't well updated when moving to external display.
// Currently we do a workaround is to check if IME is moving to new display, if so,
// create new display context and re-init keyboard layout with this context.
final WindowManager wm = getSystemService(WindowManager.class);
final int newDisplayId = wm.getDefaultDisplay().getDisplayId();
if (mCurDisplayId != newDisplayId || !mDisplayContext.getResources().getConfiguration()
.equals(getResources().getConfiguration())) {
mCurDisplayId = newDisplayId;
mDisplayContext = createDisplayContext(wm.getDefaultDisplay());
mKeyboardSwitcher.updateKeyboardTheme(mDisplayContext);
mDisplayContext = getDisplayContext();
mKeyboardSwitcher.updateKeyboardTheme(mDisplayContext);
}
/**
* Returns the context object whose resources are adjusted to match the metrics of the display.
*
* Note that before {@link android.os.Build.VERSION_CODES#KITKAT}, there is no way to support
* multi-display scenarios, so the context object will just return the IME context itself.
*
* With initiating multi-display APIs from {@link android.os.Build.VERSION_CODES#KITKAT}, the
* context object has to return with re-creating the display context according the metrics
* of the display in runtime.
*
* Starts from {@link android.os.Build.VERSION_CODES#S_V2}, the returning context object has
* became to IME context self since it ends up capable of updating its resources internally.
*
* @see android.content.Context#createDisplayContext(Display)
*/
private @NonNull Context getDisplayContext() {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
// createDisplayContext is not available.
return this;
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S_V2) {
// IME context sources is now managed by WindowProviderService from Android 12L.
return this;
}
// An issue in Q that non-activity components Resources / DisplayMetrics in
// Context doesn't well updated when the IME window moving to external display.
// Currently we do a workaround is to create new display context directly and re-init
// keyboard layout with this context.
final WindowManager wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
return createDisplayContext(wm.getDefaultDisplay());
}
@Override