Plumb IME subtype change from IMMS to IMS (again)

This CL introduces

  onInputMethodSubtypeChangedForKeyboardLayoutMapping()

to

  InputManagerInternal

in a way that is similar to our previous attempt [1].

The two major differences are

 A. It also provides InputMethodSubtypeHandle so that
    InputManagerService can use it as look up keys, and

 B. Subtypes that return false from
      isSuitableForPhysicalKeyboardLayoutMapping() [2]
    are mapped to null.

Other than those two differences, this CL is the same as our previous
CL [1].

See also another previous CL [3] about how this callback can be used.

 [1]: I58e71ffce9ac9131551a00dd35e24235dadfef87
      b097b8262b
 [2]: Ifc0247041a43ef64f8a76a23832da2ee058c6958
      6980a434cd
 [3]: Ie88ce1ab77dbfe03ab51d89c1dc9e0a7ddbb3216
      d5f7ed9fe9

Bug: 252816846
Test: manually verified
Change-Id: I087f02d06dc5575d2e657c25614d0361ef2ff443
This commit is contained in:
Yohei Yukawa
2022-11-07 09:40:48 -08:00
parent 9caeec5dd8
commit f341715288
3 changed files with 60 additions and 0 deletions

View File

@@ -17,10 +17,15 @@
package com.android.server.input;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UserIdInt;
import android.graphics.PointF;
import android.hardware.display.DisplayViewport;
import android.os.IBinder;
import android.view.InputChannel;
import android.view.inputmethod.InputMethodSubtype;
import com.android.internal.inputmethod.InputMethodSubtypeHandle;
import java.util.List;
@@ -135,6 +140,26 @@ public abstract class InputManagerInternal {
/** Create an {@link InputChannel} that is registered to InputDispatcher. */
public abstract InputChannel createInputChannel(String inputChannelName);
/**
* Pilfer pointers from the input channel with the given token so that ongoing gestures are
* canceled for all other channels.
*/
public abstract void pilferPointers(IBinder token);
/**
* Called when the current input method and/or {@link InputMethodSubtype} is updated.
*
* @param userId User ID to be notified about.
* @param subtypeHandle A {@link InputMethodSubtypeHandle} corresponds to {@code subtype}.
* @param subtype A {@link InputMethodSubtype} object, or {@code null} when the current
* {@link InputMethodSubtype} is not suitable for the physical keyboard layout
* mapping.
* @see InputMethodSubtype#isSuitableForPhysicalKeyboardLayoutMapping()
*/
public abstract void onInputMethodSubtypeChangedForKeyboardLayoutMapping(@UserIdInt int userId,
@Nullable InputMethodSubtypeHandle subtypeHandle,
@Nullable InputMethodSubtype subtype);
/**
* Increments keyboard backlight level if the device has an associated keyboard backlight
* {@see Light.LIGHT_TYPE_KEYBOARD_BACKLIGHT}

View File

@@ -23,6 +23,7 @@ import android.Manifest;
import android.annotation.EnforcePermission;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UserIdInt;
import android.app.ActivityManagerInternal;
import android.app.Notification;
import android.app.NotificationManager;
@@ -110,11 +111,13 @@ import android.view.Surface;
import android.view.SurfaceControl;
import android.view.VerifiedInputEvent;
import android.view.ViewConfiguration;
import android.view.inputmethod.InputMethodSubtype;
import android.widget.Toast;
import com.android.internal.R;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.inputmethod.InputMethodSubtypeHandle;
import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
import com.android.internal.notification.SystemNotificationChannels;
import com.android.internal.os.SomeArgs;
@@ -3781,6 +3784,21 @@ public class InputManagerService extends IInputManager.Stub
return InputManagerService.this.createInputChannel(inputChannelName);
}
@Override
public void pilferPointers(IBinder token) {
mNative.pilferPointers(token);
}
@Override
public void onInputMethodSubtypeChangedForKeyboardLayoutMapping(@UserIdInt int userId,
@Nullable InputMethodSubtypeHandle subtypeHandle,
@Nullable InputMethodSubtype subtype) {
if (DEBUG) {
Slog.i(TAG, "InputMethodSubtype changed: userId=" + userId
+ " subtypeHandle=" + subtypeHandle);
}
}
@Override
public void incrementKeyboardBacklight(int deviceId) {
mKeyboardBacklightController.incrementKeyboardBacklight(deviceId);

View File

@@ -162,6 +162,7 @@ import com.android.internal.inputmethod.InlineSuggestionsRequestInfo;
import com.android.internal.inputmethod.InputBindResult;
import com.android.internal.inputmethod.InputMethodDebug;
import com.android.internal.inputmethod.InputMethodNavButtonFlags;
import com.android.internal.inputmethod.InputMethodSubtypeHandle;
import com.android.internal.inputmethod.SoftInputShowHideReason;
import com.android.internal.inputmethod.StartInputFlags;
import com.android.internal.inputmethod.StartInputReason;
@@ -3200,6 +3201,18 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
sendOnNavButtonFlagsChangedLocked();
}
@GuardedBy("ImfLock.class")
private void notifyInputMethodSubtypeChangedLocked(@UserIdInt int userId,
@NonNull InputMethodInfo imi, @Nullable InputMethodSubtype subtype) {
final InputMethodSubtype normalizedSubtype =
subtype != null && subtype.isSuitableForPhysicalKeyboardLayoutMapping()
? subtype : null;
final InputMethodSubtypeHandle newSubtypeHandle = normalizedSubtype != null
? InputMethodSubtypeHandle.of(imi, normalizedSubtype) : null;
mInputManagerInternal.onInputMethodSubtypeChangedForKeyboardLayoutMapping(
userId, newSubtypeHandle, normalizedSubtype);
}
@GuardedBy("ImfLock.class")
void setInputMethodLocked(String id, int subtypeId) {
InputMethodInfo info = mMethodMap.get(id);
@@ -3209,8 +3222,10 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
// See if we need to notify a subtype change within the same IME.
if (id.equals(getSelectedMethodIdLocked())) {
final int userId = mSettings.getCurrentUserId();
final int subtypeCount = info.getSubtypeCount();
if (subtypeCount <= 0) {
notifyInputMethodSubtypeChangedLocked(userId, info, null);
return;
}
final InputMethodSubtype oldSubtype = mCurrentSubtype;
@@ -3225,6 +3240,7 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
if (newSubtype == null || oldSubtype == null) {
Slog.w(TAG, "Illegal subtype state: old subtype = " + oldSubtype
+ ", new subtype = " + newSubtype);
notifyInputMethodSubtypeChangedLocked(userId, info, null);
return;
}
if (newSubtype != oldSubtype) {
@@ -5297,6 +5313,7 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
mCurrentSubtype = getCurrentInputMethodSubtypeLocked();
}
}
notifyInputMethodSubtypeChangedLocked(mSettings.getCurrentUserId(), imi, mCurrentSubtype);
if (!setSubtypeOnly) {
// Set InputMethod here