Merge changes from topic "inline-touch"

* changes:
  Change when to create inline fill request
  Add new IME attr
This commit is contained in:
TreeHugger Robot
2022-02-16 06:16:35 +00:00
committed by Android (Google) Code Review
8 changed files with 111 additions and 17 deletions

View File

@@ -1453,6 +1453,7 @@ package android {
field public static final int supportsAssist = 16844016; // 0x10104f0
field public static final int supportsBatteryGameMode;
field public static final int supportsInlineSuggestions = 16844301; // 0x101060d
field public static final int supportsInlineSuggestionsWithTouchExploration;
field public static final int supportsLaunchVoiceAssistFromKeyguard = 16844017; // 0x10104f1
field public static final int supportsLocalInteraction = 16844047; // 0x101050f
field public static final int supportsMultipleDisplays = 16844182; // 0x1010596

View File

@@ -64,6 +64,7 @@ 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_supportsInlineSuggestionsWithTouchExploration
* @attr ref android.R.styleable#InputMethod_suppressesSpellChecker
* @attr ref android.R.styleable#InputMethod_showInInputMethodPicker
* @attr ref android.R.styleable#InputMethod_configChanges
@@ -124,6 +125,11 @@ public final class InputMethodInfo implements Parcelable {
*/
private final boolean mInlineSuggestionsEnabled;
/**
* The flag whether this IME supports inline suggestions when touch exploration is enabled.
*/
private final boolean mSupportsInlineSuggestionsWithTouchExploration;
/**
* The flag whether this IME suppresses spell checker.
*/
@@ -189,6 +195,7 @@ public final class InputMethodInfo implements Parcelable {
boolean isAuxIme = true;
boolean supportsSwitchingToNextInputMethod = false; // false as default
boolean inlineSuggestionsEnabled = false; // false as default
boolean supportsInlineSuggestionsWithTouchExploration = false; // false as default
boolean suppressesSpellChecker = false; // false as default
boolean showInInputMethodPicker = true; // true as default
mForceDefault = false;
@@ -234,6 +241,9 @@ public final class InputMethodInfo implements Parcelable {
false);
inlineSuggestionsEnabled = sa.getBoolean(
com.android.internal.R.styleable.InputMethod_supportsInlineSuggestions, false);
supportsInlineSuggestionsWithTouchExploration = sa.getBoolean(
com.android.internal.R.styleable
.InputMethod_supportsInlineSuggestionsWithTouchExploration, false);
suppressesSpellChecker = sa.getBoolean(
com.android.internal.R.styleable.InputMethod_suppressesSpellChecker, false);
showInInputMethodPicker = sa.getBoolean(
@@ -314,6 +324,8 @@ public final class InputMethodInfo implements Parcelable {
mIsAuxIme = isAuxIme;
mSupportsSwitchingToNextInputMethod = supportsSwitchingToNextInputMethod;
mInlineSuggestionsEnabled = inlineSuggestionsEnabled;
mSupportsInlineSuggestionsWithTouchExploration =
supportsInlineSuggestionsWithTouchExploration;
mSuppressesSpellChecker = suppressesSpellChecker;
mShowInInputMethodPicker = showInInputMethodPicker;
mIsVrOnly = isVrOnly;
@@ -326,6 +338,7 @@ public final class InputMethodInfo implements Parcelable {
mIsAuxIme = source.readInt() == 1;
mSupportsSwitchingToNextInputMethod = source.readInt() == 1;
mInlineSuggestionsEnabled = source.readInt() == 1;
mSupportsInlineSuggestionsWithTouchExploration = source.readInt() == 1;
mSuppressesSpellChecker = source.readBoolean();
mShowInInputMethodPicker = source.readBoolean();
mIsVrOnly = source.readBoolean();
@@ -345,7 +358,8 @@ public final class InputMethodInfo implements Parcelable {
settingsActivity, null /* subtypes */, 0 /* isDefaultResId */,
false /* forceDefault */, true /* supportsSwitchingToNextInputMethod */,
false /* inlineSuggestionsEnabled */, false /* isVrOnly */,
0 /* handledConfigChanges */, false /* supportsStylusHandwriting */);
0 /* handledConfigChanges */, false /* supportsStylusHandwriting */,
false /* inlineSuggestionsEnabled */);
}
/**
@@ -360,7 +374,8 @@ public final class InputMethodInfo implements Parcelable {
settingsActivity, null /* subtypes */, 0 /* isDefaultResId */,
false /* forceDefault */, true /* supportsSwitchingToNextInputMethod */,
false /* inlineSuggestionsEnabled */, false /* isVrOnly */, handledConfigChanges,
false /* supportsStylusHandwriting */);
false /* supportsStylusHandwriting */,
false /* inlineSuggestionsEnabled */);
}
/**
@@ -373,7 +388,8 @@ public final class InputMethodInfo implements Parcelable {
this(ri, isAuxIme, settingsActivity, subtypes, isDefaultResId, forceDefault,
true /* supportsSwitchingToNextInputMethod */, false /* inlineSuggestionsEnabled */,
false /* isVrOnly */, 0 /* handledconfigChanges */,
false /* supportsStylusHandwriting */);
false /* supportsStylusHandwriting */,
false /* inlineSuggestionsEnabled */);
}
/**
@@ -385,7 +401,8 @@ public final class InputMethodInfo implements Parcelable {
boolean supportsSwitchingToNextInputMethod, boolean isVrOnly) {
this(ri, isAuxIme, settingsActivity, subtypes, isDefaultResId, forceDefault,
supportsSwitchingToNextInputMethod, false /* inlineSuggestionsEnabled */, isVrOnly,
0 /* handledConfigChanges */, false /* supportsStylusHandwriting */);
0 /* handledConfigChanges */, false /* supportsStylusHandwriting */,
false /* inlineSuggestionsEnabled */);
}
/**
@@ -395,7 +412,8 @@ 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 supportsStylusHandwriting) {
boolean isVrOnly, int handledConfigChanges, boolean supportsStylusHandwriting,
boolean supportsInlineSuggestionsWithTouchExploration) {
final ServiceInfo si = ri.serviceInfo;
mService = ri;
mId = new ComponentName(si.packageName, si.name).flattenToShortString();
@@ -406,6 +424,8 @@ public final class InputMethodInfo implements Parcelable {
mForceDefault = forceDefault;
mSupportsSwitchingToNextInputMethod = supportsSwitchingToNextInputMethod;
mInlineSuggestionsEnabled = inlineSuggestionsEnabled;
mSupportsInlineSuggestionsWithTouchExploration =
supportsInlineSuggestionsWithTouchExploration;
mSuppressesSpellChecker = false;
mShowInInputMethodPicker = true;
mIsVrOnly = isVrOnly;
@@ -583,6 +603,8 @@ public final class InputMethodInfo implements Parcelable {
+ " mIsVrOnly=" + mIsVrOnly
+ " mSupportsSwitchingToNextInputMethod=" + mSupportsSwitchingToNextInputMethod
+ " mInlineSuggestionsEnabled=" + mInlineSuggestionsEnabled
+ " mSupportsInlineSuggestionsWithTouchExploration="
+ mSupportsInlineSuggestionsWithTouchExploration
+ " mSuppressesSpellChecker=" + mSuppressesSpellChecker
+ " mShowInInputMethodPicker=" + mShowInInputMethodPicker
+ " mSupportsStylusHandwriting=" + mSupportsStylusHandwriting);
@@ -653,6 +675,15 @@ public final class InputMethodInfo implements Parcelable {
return mInlineSuggestionsEnabled;
}
/**
* Returns {@code true} if this input method supports inline suggestions when touch exploration
* is enabled.
* @hide
*/
public boolean supportsInlineSuggestionsWithTouchExploration() {
return mSupportsInlineSuggestionsWithTouchExploration;
}
/**
* Return {@code true} if this input method suppresses spell checker.
*/
@@ -683,6 +714,7 @@ public final class InputMethodInfo implements Parcelable {
dest.writeInt(mIsAuxIme ? 1 : 0);
dest.writeInt(mSupportsSwitchingToNextInputMethod ? 1 : 0);
dest.writeInt(mInlineSuggestionsEnabled ? 1 : 0);
dest.writeInt(mSupportsInlineSuggestionsWithTouchExploration ? 1 : 0);
dest.writeBoolean(mSuppressesSpellChecker);
dest.writeBoolean(mShowInInputMethodPicker);
dest.writeBoolean(mIsVrOnly);

View File

@@ -3644,6 +3644,14 @@
<attr name="__removed2" format="boolean" />
<!-- Specifies whether the IME supports showing inline suggestions. -->
<attr name="supportsInlineSuggestions" format="boolean" />
<!-- Specifies whether the IME supports showing inline suggestions when touch
exploration is enabled. This does nothing if supportsInlineSuggestions is false.
The default value is false and most IMEs should not set this
to true since the older menu-style Autofill works better with touch exploration.
This attribute should be set to true in special situations, such as if this is an
accessibility-focused IME which blocks user interaction with the app window while the
IME is displayed. -->
<attr name="supportsInlineSuggestionsWithTouchExploration" format="boolean" />
<!-- Specifies whether the IME suppresses system spell checker.
The default value is false. If an IME sets this attribute to true,
the system spell checker will be disabled while the IME has an

View File

@@ -3280,6 +3280,7 @@
<public name="knownActivityEmbeddingCerts" />
<public name="intro" />
<public name="enableOnBackInvokedCallback" />
<public name="supportsInlineSuggestionsWithTouchExploration" />
</staging-public-group>
<staging-public-group type="id" first-id="0x01de0000">

View File

@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (C) 2022 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.
-->
<input-method
xmlns:android="http://schemas.android.com/apk/res/android"
android:settingsActivity="com.android.inputmethod.latin.settings.SettingsActivity"
android:supportsInlineSuggestionsWithTouchExploration="true"
>
<subtype
android:label="subtype1"
android:imeSubtypeLocale="en_US"
android:imeSubtypeMode="keyboard" />
</input-method>

View File

@@ -55,11 +55,13 @@ public class InputMethodInfoTest {
assertThat(imi.supportsSwitchingToNextInputMethod(), is(false));
assertThat(imi.isInlineSuggestionsEnabled(), is(false));
assertThat(imi.supportsInlineSuggestionsWithTouchExploration(), is(false));
final InputMethodInfo clone = cloneViaParcel(imi);
assertThat(clone.supportsSwitchingToNextInputMethod(), is(false));
assertThat(imi.isInlineSuggestionsEnabled(), is(false));
assertThat(imi.supportsInlineSuggestionsWithTouchExploration(), is(false));
}
@Test
@@ -84,6 +86,18 @@ public class InputMethodInfoTest {
assertThat(clone.isInlineSuggestionsEnabled(), is(true));
}
@Test
public void testInlineSuggestionsEnabledWithTouchExploration() throws Exception {
final InputMethodInfo imi =
buildInputMethodForTest(R.xml.ime_meta_inline_suggestions_with_touch_exploration);
assertThat(imi.supportsInlineSuggestionsWithTouchExploration(), is(true));
final InputMethodInfo clone = cloneViaParcel(imi);
assertThat(clone.supportsInlineSuggestionsWithTouchExploration(), is(true));
}
@Test
public void testIsVrOnly() throws Exception {
final InputMethodInfo imi = buildInputMethodForTest(R.xml.ime_meta_vr_only);

View File

@@ -103,7 +103,6 @@ import android.util.Slog;
import android.util.SparseArray;
import android.util.TimeUtils;
import android.view.KeyEvent;
import android.view.accessibility.AccessibilityManager;
import android.view.autofill.AutofillId;
import android.view.autofill.AutofillManager;
import android.view.autofill.AutofillManager.SmartSuggestionMode;
@@ -367,8 +366,6 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
@Nullable
private ClientSuggestionsSession mClientSuggestionsSession;
private final AccessibilityManager mAccessibilityManager;
// TODO(b/216576510): Share one BroadcastReceiver between all Sessions instead of creating a
// new one per Session.
private final BroadcastReceiver mDelayedFillBroadcastReceiver =
@@ -518,10 +515,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
return;
}
// If a11y touch exploration is enabled, then we do not send an inline fill request
// to the regular af service, because dropdown UI is easier to use.
if (mPendingInlineSuggestionsRequest.isServiceSupported()
&& !mAccessibilityManager.isTouchExplorationEnabled()) {
if (mPendingInlineSuggestionsRequest.isServiceSupported()) {
mPendingFillRequest = new FillRequest(mPendingFillRequest.getId(),
mPendingFillRequest.getFillContexts(),
mPendingFillRequest.getClientState(),
@@ -1064,7 +1058,6 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
mRemoteFillService = serviceComponentName == null ? null
: new RemoteFillService(context, serviceComponentName, userId, this,
bindInstantServiceAllowed);
mAccessibilityManager = AccessibilityManager.getInstance(context);
mActivityToken = activityToken;
mHasCallback = hasCallback;
mUiLatencyHistory = uiLatencyHistory;

View File

@@ -130,6 +130,7 @@ import android.view.WindowManager;
import android.view.WindowManager.DisplayImePolicy;
import android.view.WindowManager.LayoutParams;
import android.view.WindowManager.LayoutParams.SoftInputModeFlags;
import android.view.accessibility.AccessibilityManager;
import android.view.autofill.AutofillId;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InlineSuggestionsRequest;
@@ -287,6 +288,9 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
private final InputMethodMenuController mMenuController;
private final InputMethodBindingController mBindingController;
// TODO(b/219056452): Use AccessibilityManagerInternal instead.
private final AccessibilityManager mAccessibilityManager;
/**
* Cache the result of {@code LocalServices.getService(AudioManagerInternal.class)}.
*
@@ -1627,6 +1631,7 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
mAppOpsManager = mContext.getSystemService(AppOpsManager.class);
mUserManager = mContext.getSystemService(UserManager.class);
mUserManagerInternal = LocalServices.getService(UserManagerInternal.class);
mAccessibilityManager = AccessibilityManager.getInstance(context);
mHasFeature = context.getPackageManager().hasSystemFeature(
PackageManager.FEATURE_INPUT_METHODS);
mPlatformCompat = IPlatformCompat.Stub.asInterface(
@@ -1995,12 +2000,13 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
@GuardedBy("ImfLock.class")
private void onCreateInlineSuggestionsRequestLocked(@UserIdInt int userId,
InlineSuggestionsRequestInfo requestInfo, IInlineSuggestionsRequestCallback callback) {
InlineSuggestionsRequestInfo requestInfo, IInlineSuggestionsRequestCallback callback,
boolean touchExplorationEnabled) {
final InputMethodInfo imi = mMethodMap.get(getSelectedMethodIdLocked());
try {
IInputMethodInvoker curMethod = getCurMethodLocked();
if (userId == mSettings.getCurrentUserId() && imi != null
&& imi.isInlineSuggestionsEnabled() && curMethod != null) {
if (userId == mSettings.getCurrentUserId() && curMethod != null
&& imi != null && isInlineSuggestionsEnabled(imi, touchExplorationEnabled)) {
final IInlineSuggestionsRequestCallback callbackImpl =
new InlineSuggestionsRequestCallbackDecorator(callback,
imi.getPackageName(), mCurTokenDisplayId, getCurTokenLocked(),
@@ -2014,6 +2020,13 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
}
}
private static boolean isInlineSuggestionsEnabled(InputMethodInfo imi,
boolean touchExplorationEnabled) {
return imi.isInlineSuggestionsEnabled()
&& (!touchExplorationEnabled
|| imi.supportsInlineSuggestionsWithTouchExploration());
}
/**
* The decorator which validates the host package name in the
* {@link InlineSuggestionsRequest} argument to make sure it matches the IME package name.
@@ -5197,8 +5210,12 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
@Override
public void onCreateInlineSuggestionsRequest(@UserIdInt int userId,
InlineSuggestionsRequestInfo requestInfo, IInlineSuggestionsRequestCallback cb) {
// Get the device global touch exploration state before lock to avoid deadlock.
boolean touchExplorationEnabled = mAccessibilityManager.isTouchExplorationEnabled();
synchronized (ImfLock.class) {
onCreateInlineSuggestionsRequestLocked(userId, requestInfo, cb);
onCreateInlineSuggestionsRequestLocked(userId, requestInfo, cb,
touchExplorationEnabled);
}
}