Revert "Avoid IME restart for configChanges"
Revert "Add cts for InputMethodService configChanges" Revert submission 13727407-167948419 Reason for revert: Possible root cause of Bug 182604598. Reverted Changes: Ib94fddadb:Avoid IME restart for configChanges Ieca327b2e:Add cts for InputMethodService configChanges Bug: 167948419 Bug: 182604598 Test: presubmit Change-Id: I3accc55ac65d0e2ec30c3f6023680fda27ad3e97
This commit is contained in:
@@ -51290,7 +51290,6 @@ package android.view.inputmethod {
|
||||
method public int describeContents();
|
||||
method public void dump(android.util.Printer, String);
|
||||
method public android.content.ComponentName getComponent();
|
||||
method public int getConfigChanges();
|
||||
method public String getId();
|
||||
method public int getIsDefaultResourceId();
|
||||
method public String getPackageName();
|
||||
|
||||
@@ -2663,10 +2663,6 @@ package android.view.inputmethod {
|
||||
method @NonNull public static android.view.inputmethod.InlineSuggestionsResponse newInlineSuggestionsResponse(@NonNull java.util.List<android.view.inputmethod.InlineSuggestion>);
|
||||
}
|
||||
|
||||
public final class InputMethodInfo implements android.os.Parcelable {
|
||||
ctor public InputMethodInfo(@NonNull String, @NonNull String, @NonNull CharSequence, @NonNull String, int);
|
||||
}
|
||||
|
||||
public final class InputMethodManager {
|
||||
method public int getDisplayId();
|
||||
method public boolean hasActiveInputConnection(@Nullable android.view.View);
|
||||
|
||||
@@ -171,7 +171,7 @@ class IInputMethodWrapper extends IInputMethod.Stub
|
||||
SomeArgs args = (SomeArgs) msg.obj;
|
||||
try {
|
||||
inputMethod.initializeInternal((IBinder) args.arg1, msg.arg1,
|
||||
(IInputMethodPrivilegedOperations) args.arg2, (int) args.arg3);
|
||||
(IInputMethodPrivilegedOperations) args.arg2);
|
||||
} finally {
|
||||
args.recycle();
|
||||
}
|
||||
@@ -280,10 +280,9 @@ class IInputMethodWrapper extends IInputMethod.Stub
|
||||
@BinderThread
|
||||
@Override
|
||||
public void initializeInternal(IBinder token, int displayId,
|
||||
IInputMethodPrivilegedOperations privOps, int configChanges) {
|
||||
IInputMethodPrivilegedOperations privOps) {
|
||||
mCaller.executeOrSendMessage(
|
||||
mCaller.obtainMessageIOOO(DO_INITIALIZE_INTERNAL, displayId, token, privOps,
|
||||
configChanges));
|
||||
mCaller.obtainMessageIOO(DO_INITIALIZE_INTERNAL, displayId, token, privOps));
|
||||
}
|
||||
|
||||
@BinderThread
|
||||
|
||||
@@ -70,7 +70,6 @@ import android.compat.annotation.ChangeId;
|
||||
import android.compat.annotation.EnabledSince;
|
||||
import android.compat.annotation.UnsupportedAppUsage;
|
||||
import android.content.Context;
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.res.Configuration;
|
||||
import android.content.res.Resources;
|
||||
@@ -132,7 +131,6 @@ import android.widget.TextView;
|
||||
import android.window.WindowMetricsHelper;
|
||||
|
||||
import com.android.internal.annotations.GuardedBy;
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.internal.inputmethod.IInputContentUriToken;
|
||||
import com.android.internal.inputmethod.IInputMethodPrivilegedOperations;
|
||||
import com.android.internal.inputmethod.InputMethodPrivilegedOperations;
|
||||
@@ -515,8 +513,6 @@ public class InputMethodService extends AbstractInputMethodService {
|
||||
private boolean mIsAutomotive;
|
||||
private Handler mHandler;
|
||||
private boolean mImeSurfaceScheduledForRemoval;
|
||||
private Configuration mLastKnownConfig;
|
||||
private int mHandledConfigChanges;
|
||||
|
||||
/**
|
||||
* An opaque {@link Binder} token of window requesting {@link InputMethodImpl#showSoftInput}
|
||||
@@ -592,13 +588,12 @@ public class InputMethodService extends AbstractInputMethodService {
|
||||
@MainThread
|
||||
@Override
|
||||
public final void initializeInternal(@NonNull IBinder token, int displayId,
|
||||
IInputMethodPrivilegedOperations privilegedOperations, int configChanges) {
|
||||
IInputMethodPrivilegedOperations privilegedOperations) {
|
||||
if (InputMethodPrivilegedOperationsRegistry.isRegistered(token)) {
|
||||
Log.w(TAG, "The token has already registered, ignore this initialization.");
|
||||
return;
|
||||
}
|
||||
Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "IMS.initializeInternal");
|
||||
mHandledConfigChanges = configChanges;
|
||||
mPrivOps.set(privilegedOperations);
|
||||
InputMethodPrivilegedOperationsRegistry.put(token, mPrivOps);
|
||||
updateInputMethodDisplay(displayId);
|
||||
@@ -826,9 +821,6 @@ public class InputMethodService extends AbstractInputMethodService {
|
||||
setImeWindowStatus(mapToImeWindowStatus(), mBackDisposition);
|
||||
}
|
||||
final boolean isVisible = isInputViewShown();
|
||||
if (isVisible && getResources() != null) {
|
||||
mLastKnownConfig = new Configuration(getResources().getConfiguration());
|
||||
}
|
||||
final boolean visibilityChanged = isVisible != wasVisible;
|
||||
if (resultReceiver != null) {
|
||||
resultReceiver.send(visibilityChanged
|
||||
@@ -1436,30 +1428,10 @@ public class InputMethodService extends AbstractInputMethodService {
|
||||
* state: {@link #onStartInput} if input is active, and
|
||||
* {@link #onCreateInputView} and {@link #onStartInputView} and related
|
||||
* appropriate functions if the UI is displayed.
|
||||
* <p>Starting with {@link Build.VERSION_CODES#S}, IMEs can opt into handling configuration
|
||||
* changes themselves instead of being restarted with
|
||||
* {@link android.R.styleable#InputMethod_configChanges}.
|
||||
*/
|
||||
@Override public void onConfigurationChanged(Configuration newConfig) {
|
||||
super.onConfigurationChanged(newConfig);
|
||||
if (shouldImeRestartForConfig(newConfig)) {
|
||||
resetStateForNewConfiguration();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {@code true} if {@link InputMethodService} needs to restart to handle
|
||||
* .{@link #onConfigurationChanged(Configuration)}
|
||||
*/
|
||||
@VisibleForTesting
|
||||
boolean shouldImeRestartForConfig(@NonNull Configuration newConfig) {
|
||||
if (mLastKnownConfig == null) {
|
||||
return true;
|
||||
}
|
||||
// If the new config is the same as the config this Service is already running with,
|
||||
// then don't bother calling resetStateForNewConfiguration.
|
||||
int unhandledDiff = (mLastKnownConfig.diffPublicOnly(newConfig) & ~mHandledConfigChanges);
|
||||
return unhandledDiff != 0;
|
||||
resetStateForNewConfiguration();
|
||||
}
|
||||
|
||||
private void resetStateForNewConfiguration() {
|
||||
@@ -3209,17 +3181,7 @@ public class InputMethodService extends AbstractInputMethodService {
|
||||
requestHideSelf(InputMethodManager.HIDE_NOT_ALWAYS);
|
||||
}
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void setLastKnownConfig(@NonNull Configuration config) {
|
||||
mLastKnownConfig = config;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void setHandledConfigChanges(int configChanges) {
|
||||
mHandledConfigChanges = configChanges;
|
||||
}
|
||||
|
||||
|
||||
void startExtractingText(boolean inputChanged) {
|
||||
final ExtractEditText eet = mExtractEditText;
|
||||
if (eet != null && getCurrentInputStarted()
|
||||
|
||||
@@ -105,7 +105,7 @@ public interface InputMethod {
|
||||
*/
|
||||
@MainThread
|
||||
default void initializeInternal(IBinder token, int displayId,
|
||||
IInputMethodPrivilegedOperations privilegedOperations, int configChanges) {
|
||||
IInputMethodPrivilegedOperations privilegedOperations) {
|
||||
updateInputMethodDisplay(displayId);
|
||||
attachToken(token);
|
||||
}
|
||||
|
||||
@@ -18,23 +18,19 @@ package android.view.inputmethod;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.annotation.TestApi;
|
||||
import android.compat.annotation.UnsupportedAppUsage;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.PackageManager.NameNotFoundException;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.content.pm.ServiceInfo;
|
||||
import android.content.res.Configuration;
|
||||
import android.content.res.Resources;
|
||||
import android.content.res.Resources.NotFoundException;
|
||||
import android.content.res.TypedArray;
|
||||
import android.content.res.XmlResourceParser;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.inputmethodservice.InputMethodService;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.util.AttributeSet;
|
||||
@@ -64,7 +60,6 @@ import java.util.List;
|
||||
* @attr ref android.R.styleable#InputMethod_isDefault
|
||||
* @attr ref android.R.styleable#InputMethod_supportsSwitchingToNextInputMethod
|
||||
* @attr ref android.R.styleable#InputMethod_supportsInlineSuggestions
|
||||
* @attr ref android.R.styleable#InputMethod_configChanges
|
||||
*/
|
||||
public final class InputMethodInfo implements Parcelable {
|
||||
static final String TAG = "InputMethodInfo";
|
||||
@@ -122,12 +117,6 @@ public final class InputMethodInfo implements Parcelable {
|
||||
*/
|
||||
private final boolean mInlineSuggestionsEnabled;
|
||||
|
||||
/**
|
||||
* The flag for configurations IME assumes the responsibility for handling in
|
||||
* {@link InputMethodService#onConfigurationChanged(Configuration)}}.
|
||||
*/
|
||||
private final int mHandledConfigChanges;
|
||||
|
||||
/**
|
||||
* @param service the {@link ResolveInfo} corresponds in which the IME is implemented.
|
||||
* @return a unique ID to be returned by {@link #getId()}. We have used
|
||||
@@ -214,8 +203,6 @@ public final class InputMethodInfo implements Parcelable {
|
||||
false);
|
||||
inlineSuggestionsEnabled = sa.getBoolean(
|
||||
com.android.internal.R.styleable.InputMethod_supportsInlineSuggestions, false);
|
||||
mHandledConfigChanges = sa.getInt(
|
||||
com.android.internal.R.styleable.InputMethod_configChanges, 0);
|
||||
sa.recycle();
|
||||
|
||||
final int depth = parser.getDepth();
|
||||
@@ -300,7 +287,6 @@ public final class InputMethodInfo implements Parcelable {
|
||||
mIsVrOnly = source.readBoolean();
|
||||
mService = ResolveInfo.CREATOR.createFromParcel(source);
|
||||
mSubtypes = new InputMethodSubtypeArray(source);
|
||||
mHandledConfigChanges = source.readInt();
|
||||
mForceDefault = false;
|
||||
}
|
||||
|
||||
@@ -312,22 +298,7 @@ public final class InputMethodInfo implements Parcelable {
|
||||
this(buildFakeResolveInfo(packageName, className, label), false /* isAuxIme */,
|
||||
settingsActivity, null /* subtypes */, 0 /* isDefaultResId */,
|
||||
false /* forceDefault */, true /* supportsSwitchingToNextInputMethod */,
|
||||
false /* inlineSuggestionsEnabled */, false /* isVrOnly */,
|
||||
0 /* handledConfigChanges */);
|
||||
}
|
||||
|
||||
/**
|
||||
* Temporary API for creating a built-in input method for test.
|
||||
* @hide
|
||||
*/
|
||||
@TestApi
|
||||
public InputMethodInfo(@NonNull String packageName, @NonNull String className,
|
||||
@NonNull CharSequence label, @NonNull String settingsActivity,
|
||||
int handledConfigChanges) {
|
||||
this(buildFakeResolveInfo(packageName, className, label), false /* isAuxIme */,
|
||||
settingsActivity, null /* subtypes */, 0 /* isDefaultResId */,
|
||||
false /* forceDefault */, true /* supportsSwitchingToNextInputMethod */,
|
||||
false /* inlineSuggestionsEnabled */, false /* isVrOnly */, handledConfigChanges);
|
||||
false /* inlineSuggestionsEnabled */, false /* isVrOnly */);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -339,7 +310,7 @@ public final class InputMethodInfo implements Parcelable {
|
||||
boolean forceDefault) {
|
||||
this(ri, isAuxIme, settingsActivity, subtypes, isDefaultResId, forceDefault,
|
||||
true /* supportsSwitchingToNextInputMethod */, false /* inlineSuggestionsEnabled */,
|
||||
false /* isVrOnly */, 0 /* handledconfigChanges */);
|
||||
false /* isVrOnly */);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -350,8 +321,7 @@ public final class InputMethodInfo implements Parcelable {
|
||||
List<InputMethodSubtype> subtypes, int isDefaultResId, boolean forceDefault,
|
||||
boolean supportsSwitchingToNextInputMethod, boolean isVrOnly) {
|
||||
this(ri, isAuxIme, settingsActivity, subtypes, isDefaultResId, forceDefault,
|
||||
supportsSwitchingToNextInputMethod, false /* inlineSuggestionsEnabled */, isVrOnly,
|
||||
0 /* handledConfigChanges */);
|
||||
supportsSwitchingToNextInputMethod, false /* inlineSuggestionsEnabled */, isVrOnly);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -361,7 +331,7 @@ public final class InputMethodInfo implements Parcelable {
|
||||
public InputMethodInfo(ResolveInfo ri, boolean isAuxIme, String settingsActivity,
|
||||
List<InputMethodSubtype> subtypes, int isDefaultResId, boolean forceDefault,
|
||||
boolean supportsSwitchingToNextInputMethod, boolean inlineSuggestionsEnabled,
|
||||
boolean isVrOnly, int handledConfigChanges) {
|
||||
boolean isVrOnly) {
|
||||
final ServiceInfo si = ri.serviceInfo;
|
||||
mService = ri;
|
||||
mId = new ComponentName(si.packageName, si.name).flattenToShortString();
|
||||
@@ -373,7 +343,6 @@ public final class InputMethodInfo implements Parcelable {
|
||||
mSupportsSwitchingToNextInputMethod = supportsSwitchingToNextInputMethod;
|
||||
mInlineSuggestionsEnabled = inlineSuggestionsEnabled;
|
||||
mIsVrOnly = isVrOnly;
|
||||
mHandledConfigChanges = handledConfigChanges;
|
||||
}
|
||||
|
||||
private static ResolveInfo buildFakeResolveInfo(String packageName, String className,
|
||||
@@ -520,17 +489,6 @@ public final class InputMethodInfo implements Parcelable {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the bit mask of kinds of configuration changes that this IME
|
||||
* can handle itself (without being restarted by the system).
|
||||
*
|
||||
* @attr ref android.R.styleable#InputMethod_configChanges
|
||||
*/
|
||||
@ActivityInfo.Config
|
||||
public int getConfigChanges() {
|
||||
return mHandledConfigChanges;
|
||||
}
|
||||
|
||||
public void dump(Printer pw, String prefix) {
|
||||
pw.println(prefix + "mId=" + mId
|
||||
+ " mSettingsActivityName=" + mSettingsActivityName
|
||||
@@ -621,7 +579,6 @@ public final class InputMethodInfo implements Parcelable {
|
||||
dest.writeBoolean(mIsVrOnly);
|
||||
mService.writeToParcel(dest, flags);
|
||||
mSubtypes.writeToParcel(dest);
|
||||
dest.writeInt(mHandledConfigChanges);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -35,8 +35,7 @@ import com.android.internal.view.InlineSuggestionsRequestInfo;
|
||||
* {@hide}
|
||||
*/
|
||||
oneway interface IInputMethod {
|
||||
void initializeInternal(IBinder token, int displayId, IInputMethodPrivilegedOperations privOps,
|
||||
int configChanges);
|
||||
void initializeInternal(IBinder token, int displayId, IInputMethodPrivilegedOperations privOps);
|
||||
|
||||
void onCreateInlineSuggestionsRequest(in InlineSuggestionsRequestInfo requestInfo,
|
||||
in IInlineSuggestionsRequestCallback cb);
|
||||
|
||||
@@ -3564,16 +3564,6 @@
|
||||
<attr name="__removed2" format="boolean" />
|
||||
<!-- Specifies whether the IME supports showing inline suggestions. -->
|
||||
<attr name="supportsInlineSuggestions" format="boolean" />
|
||||
<!-- Specify one or more configuration changes that the IME will handle itself. If not
|
||||
specified, the IME will be restarted if any of these configuration changes happen in
|
||||
the system. Otherwise, the IME will remain running and its
|
||||
{@link android.inputmethodservice.InputMethodService#onConfigurationChanged}
|
||||
method is called with the new configuration.
|
||||
<p>Note that all of these configuration changes can impact the
|
||||
resource values seen by the application, so you will generally need
|
||||
to re-retrieve all resources (including view layouts, drawables, etc)
|
||||
to correctly handle any configuration change.-->
|
||||
<attr name="configChanges" />
|
||||
</declare-styleable>
|
||||
|
||||
<!-- This is the subtype of InputMethod. Subtype can describe locales (for example, en_US and
|
||||
|
||||
@@ -1,83 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2021 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.inputmethodservice;
|
||||
|
||||
import static android.content.res.Configuration.KEYBOARD_12KEY;
|
||||
import static android.content.res.Configuration.NAVIGATION_NONAV;
|
||||
|
||||
import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
|
||||
|
||||
|
||||
import static junit.framework.Assert.assertFalse;
|
||||
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.content.res.Configuration;
|
||||
import android.os.Build;
|
||||
|
||||
import androidx.test.filters.SmallTest;
|
||||
import androidx.test.rule.ServiceTestRule;
|
||||
import androidx.test.runner.AndroidJUnit4;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
@SmallTest
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class InputMethodServiceTest {
|
||||
private InputMethodService mService;
|
||||
private Context mContext;
|
||||
@Rule
|
||||
public final ServiceTestRule serviceRule = new ServiceTestRule();
|
||||
|
||||
@Before
|
||||
public void setUp() throws TimeoutException {
|
||||
mContext = getInstrumentation().getContext();
|
||||
mService = new InputMethodService();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testShouldImeRestartForConfig() throws Exception {
|
||||
// Make sure we preserve Pre-S behavior i.e. Service restarts.
|
||||
mContext.getApplicationInfo().targetSdkVersion = Build.VERSION_CODES.R;
|
||||
Configuration config = mContext.getResources().getConfiguration();
|
||||
mService.setLastKnownConfig(config);
|
||||
assertTrue("IME should restart for Pre-S",
|
||||
mService.shouldImeRestartForConfig(config));
|
||||
|
||||
// IME shouldn't restart on targetSdk S+ (with no config changes).
|
||||
mContext.getApplicationInfo().targetSdkVersion = Build.VERSION_CODES.S;
|
||||
assertFalse("IME shouldn't restart for S+",
|
||||
mService.shouldImeRestartForConfig(config));
|
||||
|
||||
// Screen density changed but IME doesn't handle congfigChanges
|
||||
config.densityDpi = 99;
|
||||
assertTrue("IME should restart for unhandled configChanges",
|
||||
mService.shouldImeRestartForConfig(config));
|
||||
|
||||
// opt-in IME to handle config changes.
|
||||
mService.setHandledConfigChanges(ActivityInfo.CONFIG_DENSITY);
|
||||
assertFalse("IME shouldn't restart for S+ since it handles configChanges",
|
||||
mService.shouldImeRestartForConfig(config));
|
||||
}
|
||||
}
|
||||
@@ -2620,9 +2620,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
|
||||
}
|
||||
if (DEBUG) Slog.v(TAG, "Initiating attach with token: " + mCurToken);
|
||||
// Dispatch display id for InputMethodService to update context display.
|
||||
executeOrSendMessage(mCurMethod, mCaller.obtainMessageIOOO(
|
||||
MSG_INITIALIZE_IME, mCurTokenDisplayId, mCurMethod, mCurToken,
|
||||
mMethodMap.get(mCurMethodId).getConfigChanges()));
|
||||
executeOrSendMessage(mCurMethod, mCaller.obtainMessageIOO(
|
||||
MSG_INITIALIZE_IME, mCurTokenDisplayId, mCurMethod, mCurToken));
|
||||
scheduleNotifyImeUidToAudioService(mCurMethodUid);
|
||||
if (mCurClient != null) {
|
||||
clearClientSessionLocked(mCurClient);
|
||||
@@ -4464,8 +4463,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
|
||||
}
|
||||
final IBinder token = (IBinder) args.arg2;
|
||||
((IInputMethod) args.arg1).initializeInternal(token, msg.arg1,
|
||||
new InputMethodPrivilegedOperationsImpl(this, token),
|
||||
(int) args.arg3);
|
||||
new InputMethodPrivilegedOperationsImpl(this, token));
|
||||
} catch (RemoteException e) {
|
||||
}
|
||||
args.recycle();
|
||||
|
||||
Reference in New Issue
Block a user