Create display context when switching IME to new display for AOSP IME
To address IME service context's Resources / DisplayMetrics update when switching IME window to another display after onConfigurationChange. We use Context#createDisplayContext to create display specific context when display changed, to ensure soft keyboard can re-layout with correct resources. Bug: 126930163 Test: manual with AOSP IME as below steps: 1) Settings > Developer options > enable "Simulated Display" & "Force desktop mode". 2) Reboot device 3) Launch app (i.e. Contacts) with bluetooth or usb mouse in Simulated display. 4) Tap EditText on app to see see if IME window layout correctly on simulated display. 5) Launch app (i.e Files) on primary display. 6) Tap EditText on app to see if IME window layout correctly on primary display. Change-Id: I0ed6a079af1ed90c75fee1d36d5ce3ef3c41f8edmain
parent
bd7fbb4ccb
commit
4d464ec07d
|
@ -24,6 +24,8 @@ import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.inputmethod.EditorInfo;
|
import android.view.inputmethod.EditorInfo;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
import com.android.inputmethod.compat.InputMethodServiceCompatUtils;
|
import com.android.inputmethod.compat.InputMethodServiceCompatUtils;
|
||||||
import com.android.inputmethod.event.Event;
|
import com.android.inputmethod.event.Event;
|
||||||
import com.android.inputmethod.keyboard.KeyboardLayoutSet.KeyboardLayoutSetException;
|
import com.android.inputmethod.keyboard.KeyboardLayoutSet.KeyboardLayoutSetException;
|
||||||
|
@ -88,17 +90,19 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions {
|
||||||
InputMethodServiceCompatUtils.enableHardwareAcceleration(mLatinIME);
|
InputMethodServiceCompatUtils.enableHardwareAcceleration(mLatinIME);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateKeyboardTheme() {
|
public void updateKeyboardTheme(@NonNull Context displayContext) {
|
||||||
final boolean themeUpdated = updateKeyboardThemeAndContextThemeWrapper(
|
final boolean themeUpdated = updateKeyboardThemeAndContextThemeWrapper(
|
||||||
mLatinIME, KeyboardTheme.getKeyboardTheme(mLatinIME /* context */));
|
displayContext, KeyboardTheme.getKeyboardTheme(displayContext /* context */));
|
||||||
if (themeUpdated && mKeyboardView != null) {
|
if (themeUpdated && mKeyboardView != null) {
|
||||||
mLatinIME.setInputView(onCreateInputView(mIsHardwareAcceleratedDrawingEnabled));
|
mLatinIME.setInputView(
|
||||||
|
onCreateInputView(displayContext, mIsHardwareAcceleratedDrawingEnabled));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean updateKeyboardThemeAndContextThemeWrapper(final Context context,
|
private boolean updateKeyboardThemeAndContextThemeWrapper(final Context context,
|
||||||
final KeyboardTheme keyboardTheme) {
|
final KeyboardTheme keyboardTheme) {
|
||||||
if (mThemeContext == null || !keyboardTheme.equals(mKeyboardTheme)) {
|
if (mThemeContext == null || !keyboardTheme.equals(mKeyboardTheme)
|
||||||
|
|| !mThemeContext.getResources().equals(context.getResources())) {
|
||||||
mKeyboardTheme = keyboardTheme;
|
mKeyboardTheme = keyboardTheme;
|
||||||
mThemeContext = new ContextThemeWrapper(context, keyboardTheme.mStyleId);
|
mThemeContext = new ContextThemeWrapper(context, keyboardTheme.mStyleId);
|
||||||
KeyboardLayoutSet.onKeyboardThemeChanged();
|
KeyboardLayoutSet.onKeyboardThemeChanged();
|
||||||
|
@ -454,13 +458,14 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public View onCreateInputView(final boolean isHardwareAcceleratedDrawingEnabled) {
|
public View onCreateInputView(@NonNull Context displayContext,
|
||||||
|
final boolean isHardwareAcceleratedDrawingEnabled) {
|
||||||
if (mKeyboardView != null) {
|
if (mKeyboardView != null) {
|
||||||
mKeyboardView.closing();
|
mKeyboardView.closing();
|
||||||
}
|
}
|
||||||
|
|
||||||
updateKeyboardThemeAndContextThemeWrapper(
|
updateKeyboardThemeAndContextThemeWrapper(
|
||||||
mLatinIME, KeyboardTheme.getKeyboardTheme(mLatinIME /* context */));
|
displayContext, KeyboardTheme.getKeyboardTheme(displayContext /* context */));
|
||||||
mCurrentInputView = (InputView)LayoutInflater.from(mThemeContext).inflate(
|
mCurrentInputView = (InputView)LayoutInflater.from(mThemeContext).inflate(
|
||||||
R.layout.input_view, null);
|
R.layout.input_view, null);
|
||||||
mMainKeyboardFrame = mCurrentInputView.findViewById(R.id.main_keyboard_frame);
|
mMainKeyboardFrame = mCurrentInputView.findViewById(R.id.main_keyboard_frame);
|
||||||
|
|
|
@ -16,6 +16,8 @@
|
||||||
|
|
||||||
package com.android.inputmethod.latin;
|
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.FORCE_ASCII;
|
||||||
import static com.android.inputmethod.latin.common.Constants.ImeOption.NO_MICROPHONE;
|
import static com.android.inputmethod.latin.common.Constants.ImeOption.NO_MICROPHONE;
|
||||||
import static com.android.inputmethod.latin.common.Constants.ImeOption.NO_MICROPHONE_COMPAT;
|
import static com.android.inputmethod.latin.common.Constants.ImeOption.NO_MICROPHONE_COMPAT;
|
||||||
|
@ -107,6 +109,7 @@ import java.util.Locale;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Input method implementation for Qwerty'ish keyboard.
|
* Input method implementation for Qwerty'ish keyboard.
|
||||||
|
@ -165,6 +168,10 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
||||||
// {@link #onEvaluateInputViewShown()}.
|
// {@link #onEvaluateInputViewShown()}.
|
||||||
private boolean mIsExecutingStartShowingInputView;
|
private boolean mIsExecutingStartShowingInputView;
|
||||||
|
|
||||||
|
// 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.
|
// Object for reacting to adding/removing a dictionary pack.
|
||||||
private final BroadcastReceiver mDictionaryPackInstallReceiver =
|
private final BroadcastReceiver mDictionaryPackInstallReceiver =
|
||||||
new DictionaryPackInstallBroadcastReceiver(this);
|
new DictionaryPackInstallBroadcastReceiver(this);
|
||||||
|
@ -593,10 +600,13 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
||||||
DebugFlags.init(PreferenceManager.getDefaultSharedPreferences(this));
|
DebugFlags.init(PreferenceManager.getDefaultSharedPreferences(this));
|
||||||
RichInputMethodManager.init(this);
|
RichInputMethodManager.init(this);
|
||||||
mRichImm = RichInputMethodManager.getInstance();
|
mRichImm = RichInputMethodManager.getInstance();
|
||||||
KeyboardSwitcher.init(this);
|
|
||||||
AudioAndHapticFeedbackManager.init(this);
|
AudioAndHapticFeedbackManager.init(this);
|
||||||
AccessibilityUtils.init(this);
|
AccessibilityUtils.init(this);
|
||||||
mStatsUtilsManager.onCreate(this /* context */, mDictionaryFacilitator);
|
mStatsUtilsManager.onCreate(this /* context */, mDictionaryFacilitator);
|
||||||
|
final WindowManager wm = getSystemService(WindowManager.class);
|
||||||
|
mDisplayContext = createDisplayContext(wm.getDefaultDisplay());
|
||||||
|
mCurDisplayId = wm.getDefaultDisplay().getDisplayId();
|
||||||
|
KeyboardSwitcher.init(this);
|
||||||
super.onCreate();
|
super.onCreate();
|
||||||
|
|
||||||
mHandler.onCreate();
|
mHandler.onCreate();
|
||||||
|
@ -783,10 +793,28 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
||||||
super.onConfigurationChanged(conf);
|
super.onConfigurationChanged(conf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@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) {
|
||||||
|
mCurDisplayId = newDisplayId;
|
||||||
|
mDisplayContext = createDisplayContext(wm.getDefaultDisplay());
|
||||||
|
mKeyboardSwitcher.updateKeyboardTheme(mDisplayContext);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public View onCreateInputView() {
|
public View onCreateInputView() {
|
||||||
StatsUtils.onCreateInputView();
|
StatsUtils.onCreateInputView();
|
||||||
return mKeyboardSwitcher.onCreateInputView(mIsHardwareAcceleratedDrawingEnabled);
|
return mKeyboardSwitcher.onCreateInputView(mDisplayContext,
|
||||||
|
mIsHardwareAcceleratedDrawingEnabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -869,7 +897,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
||||||
mGestureConsumer = GestureConsumer.NULL_GESTURE_CONSUMER;
|
mGestureConsumer = GestureConsumer.NULL_GESTURE_CONSUMER;
|
||||||
mRichImm.refreshSubtypeCaches();
|
mRichImm.refreshSubtypeCaches();
|
||||||
final KeyboardSwitcher switcher = mKeyboardSwitcher;
|
final KeyboardSwitcher switcher = mKeyboardSwitcher;
|
||||||
switcher.updateKeyboardTheme();
|
switcher.updateKeyboardTheme(mDisplayContext);
|
||||||
final MainKeyboardView mainKeyboardView = switcher.getMainKeyboardView();
|
final MainKeyboardView mainKeyboardView = switcher.getMainKeyboardView();
|
||||||
// If we are starting input in a different text field from before, we'll have to reload
|
// If we are starting input in a different text field from before, we'll have to reload
|
||||||
// settings, so currentSettingsValues can't be final.
|
// settings, so currentSettingsValues can't be final.
|
||||||
|
|
Loading…
Reference in New Issue