Fix checks for showing InputMethod picker

When user tries to switch IME, IMMS.showInputMethodPickerFromClient()
is called. The call fails to validate in newly introduced
canShowInputMethodPickerLocked() in
I4f0fc21268200c64d12b31ca54416acfbf62f37b because
mCurClient.client != client.

This is happening since the new client never started input ever since
we prevented calls to startInputUncheckedLocked in
Ibf9dab3d9c138b5f04e053d41ee4fd248c78e4da.

The fix is to update mCurFocusedWindowClient.client instead of
mCurclient.client in canShowInputMethodPickerLocked()

Fixes: 72557082
Test: manually using the steps in bug
Test: atest InputMethodManagerTest
Change-Id: I4e21625c32a0ca1abc740229efb3c7fcd97141cc
This commit is contained in:
Tarandeep Singh
2018-01-29 16:20:32 -08:00
parent df2491a454
commit eb5706183f
4 changed files with 43 additions and 3 deletions

View File

@@ -1035,6 +1035,14 @@ package android.view.autofill {
}
package android.view.inputmethod {
public final class InputMethodManager {
method public boolean isInputMethodPickerShown();
}
}
package android.widget {
public abstract class AbsListView extends android.widget.AdapterView implements android.widget.Filter.FilterListener android.text.TextWatcher android.view.ViewTreeObserver.OnGlobalLayoutListener android.view.ViewTreeObserver.OnTouchModeChangeListener {

View File

@@ -22,6 +22,7 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.SystemService;
import android.annotation.TestApi;
import android.content.Context;
import android.graphics.Rect;
import android.inputmethodservice.InputMethodService;
@@ -2136,6 +2137,26 @@ public final class InputMethodManager {
}
}
/**
* A test API for CTS to make sure that {@link #showInputMethodPicker()} works as expected.
*
* <p>When customizing the implementation of {@link #showInputMethodPicker()} API, make sure
* that this test API returns when and only while and only while
* {@link #showInputMethodPicker()} is showing UI. Otherwise your OS implementation may not
* pass CTS.</p>
*
* @return {@code true} while and only while {@link #showInputMethodPicker()} is showing UI.
* @hide
*/
@TestApi
public boolean isInputMethodPickerShown() {
try {
return mService.isInputMethodPickerShownForTest();
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
/**
* Show the settings for enabling subtypes of the specified input method.
* @param imiId An input method, whose subtypes settings will be shown. If imiId is null,

View File

@@ -68,6 +68,7 @@ interface IInputMethodManager {
void showInputMethodPickerFromClient(in IInputMethodClient client,
int auxiliarySubtypeMode);
void showInputMethodAndSubtypeEnablerFromClient(in IInputMethodClient client, String topId);
boolean isInputMethodPickerShownForTest();
void setInputMethod(in IBinder token, String id);
void setInputMethodAndSubtype(in IBinder token, String id, in InputMethodSubtype subtype);
void hideMySoftInput(in IBinder token, int flags);

View File

@@ -59,6 +59,7 @@ import android.annotation.MainThread;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.TestApi;
import android.annotation.UserIdInt;
import android.app.ActivityManager;
import android.app.ActivityManagerInternal;
@@ -468,7 +469,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
int mCurFocusedWindowSoftInputMode;
/**
* The client by which {@link #mCurFocusedWindow} was reported. Used only for debugging.
* The client by which {@link #mCurFocusedWindow} was reported.
*/
ClientState mCurFocusedWindowClient;
@@ -2989,8 +2990,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
final int uid = Binder.getCallingUid();
if (UserHandle.getAppId(uid) == Process.SYSTEM_UID) {
return true;
} else if (mCurClient != null && client != null
&& mCurClient.client.asBinder() == client.asBinder()) {
} else if (mCurFocusedWindowClient != null && client != null
&& mCurFocusedWindowClient.client.asBinder() == client.asBinder()) {
return true;
} else if (mCurIntent != null && InputMethodUtils.checkIfPackageBelongsToUid(
mAppOpsManager,
@@ -3026,6 +3027,15 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
}
}
public boolean isInputMethodPickerShownForTest() {
synchronized(mMethodMap) {
if (mSwitchingDialog == null) {
return false;
}
return mSwitchingDialog.isShowing();
}
}
@Override
public void setInputMethod(IBinder token, String id) {
if (!calledFromValidUser()) {