Fix IME crash on SoftInputWindow.show by TOKEN_PENDING
Originated from CL[1] to fix a crash edge case that happened when calling InputMethodPrivilegedOperationsRegistry#put that assumes there is only one pair of window token and IInputMethodPrivilegedOperations in the container. However, InputMethodPrivilegedOperationsRegistry is a process-level singleton instances that may run into a timing when there are 2 InputMethodService (IMS) instances, one is just created and the other is in the way of destorying. Before the destorying one calls InputMethodPrivilegedOperationsRegistry#remove, IMS#initializeInternal invoked for the new one with the same window token, that makes system ignored the initialization process because CL[1] introduced InputMethodPrivilegedOperationsRegistry#isRegistered(token) and system thoughts the token has been registered before, but actually this method is problemetic to aware this token registraction is for previous IMS. As the result, IME will crash when SoftInputWindow.show because the windowState is still under TOKEN_PENDING and lose the token attachment. To fix this crash timing issue, making InputMethodPrivilegedOperationsRegistry be able to maintain more than one pairs of IME token and IInputMethodPrivilegedOperations makes more sense and we can remove the ignore logic in initializeInternal to fix the token attachment issue. [1]: Ie6bfbae735724fe744590e715124d2737d2b665d Fix: 202081442 Test: atest CtsInputMethodTestCases Test: atest MultiDisplaySystemDecorationTests Change-Id: I21cec3f228520ed703cd8ad68ea0ef59c966ed9d
This commit is contained in:
@@ -590,10 +590,6 @@ public class InputMethodService extends AbstractInputMethodService {
|
||||
@Override
|
||||
public final void initializeInternal(@NonNull IBinder token,
|
||||
IInputMethodPrivilegedOperations privilegedOperations, int configChanges) {
|
||||
if (InputMethodPrivilegedOperationsRegistry.isRegistered(token)) {
|
||||
Log.w(TAG, "The token has already registered, ignore this initialization.");
|
||||
return;
|
||||
}
|
||||
Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "IMS.initializeInternal");
|
||||
mConfigTracker.onInitialize(configChanges);
|
||||
mPrivOps.set(privilegedOperations);
|
||||
|
||||
@@ -74,12 +74,7 @@ public final class InputMethodPrivilegedOperationsRegistry {
|
||||
if (sRegistry == null) {
|
||||
sRegistry = new WeakHashMap<>();
|
||||
}
|
||||
final WeakReference<InputMethodPrivilegedOperations> previousOps =
|
||||
sRegistry.put(token, new WeakReference<>(ops));
|
||||
if (previousOps != null) {
|
||||
throw new IllegalStateException(previousOps.get() + " is already registered for "
|
||||
+ " this token=" + token + " newOps=" + ops);
|
||||
}
|
||||
sRegistry.put(token, new WeakReference<>(ops));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -132,21 +127,4 @@ public final class InputMethodPrivilegedOperationsRegistry {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check the given IME token registration status.
|
||||
*
|
||||
* @param token IME token
|
||||
* @return {@code true} when the IME token has already registered
|
||||
* {@link InputMethodPrivilegedOperations}, {@code false} otherwise.
|
||||
*/
|
||||
@AnyThread
|
||||
public static boolean isRegistered(IBinder token) {
|
||||
synchronized (sLock) {
|
||||
if (sRegistry == null) {
|
||||
return false;
|
||||
}
|
||||
return sRegistry.containsKey(token);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user