Merge "Fix MSIME client's active state"

This commit is contained in:
ycheo
2019-09-10 21:01:13 +00:00
committed by Gerrit Code Review
2 changed files with 34 additions and 12 deletions

View File

@@ -58,7 +58,7 @@ final class ClientCallbackImpl implements MultiClientInputMethodServiceDelegate.
// For simplicity, we use the main looper for this sample. // For simplicity, we use the main looper for this sample.
// To use other looper thread, make sure that the IME Window also runs on the same looper // To use other looper thread, make sure that the IME Window also runs on the same looper
// and introduce an appropriate synchronization mechanism instead of directly accessing // and introduce an appropriate synchronization mechanism instead of directly accessing
// MultiClientInputMethod#mLastClientId. // MultiClientInputMethod#mDisplayToLastClientId.
mLooper = Looper.getMainLooper(); mLooper = Looper.getMainLooper();
} }
@@ -157,11 +157,13 @@ final class ClientCallbackImpl implements MultiClientInputMethodServiceDelegate.
mDelegate.reportImeWindowTarget( mDelegate.reportImeWindowTarget(
mClientId, targetWindowHandle, window.getWindow().getAttributes().token); mClientId, targetWindowHandle, window.getWindow().getAttributes().token);
} }
final int lastClientId = mInputMethod.mDisplayToLastClientId.get(mSelfReportedDisplayId);
if (lastClientId != mClientId) {
// deactivate previous client and activate current.
mDelegate.setActive(lastClientId, false /* active */);
mDelegate.setActive(mClientId, true /* active */);
}
if (inputConnection == null || editorInfo == null) { if (inputConnection == null || editorInfo == null) {
// deactivate previous client.
if (mInputMethod.mLastClientId != mClientId) {
mDelegate.setActive(mInputMethod.mLastClientId, false /* active */);
}
// Dummy InputConnection case. // Dummy InputConnection case.
if (window.getClientId() == mClientId) { if (window.getClientId() == mClientId) {
// Special hack for temporary focus changes (e.g. notification shade). // Special hack for temporary focus changes (e.g. notification shade).
@@ -171,9 +173,6 @@ final class ClientCallbackImpl implements MultiClientInputMethodServiceDelegate.
window.onDummyStartInput(mClientId, targetWindowHandle); window.onDummyStartInput(mClientId, targetWindowHandle);
} }
} else { } else {
if (mInputMethod.mLastClientId != mClientId) {
mDelegate.setActive(mClientId, true /* active */);
}
window.onStartInput(mClientId, targetWindowHandle, inputConnection); window.onStartInput(mClientId, targetWindowHandle, inputConnection);
} }
@@ -195,7 +194,7 @@ final class ClientCallbackImpl implements MultiClientInputMethodServiceDelegate.
window.hide(); window.hide();
break; break;
} }
mInputMethod.mLastClientId = mClientId; mInputMethod.mDisplayToLastClientId.put(mSelfReportedDisplayId, mClientId);
} }
@Override @Override

View File

@@ -18,22 +18,27 @@ package com.example.android.multiclientinputmethod;
import android.app.Service; import android.app.Service;
import android.content.Intent; import android.content.Intent;
import android.hardware.display.DisplayManager;
import android.hardware.display.DisplayManager.DisplayListener;
import android.inputmethodservice.MultiClientInputMethodServiceDelegate; import android.inputmethodservice.MultiClientInputMethodServiceDelegate;
import android.os.IBinder; import android.os.IBinder;
import android.util.Log; import android.util.Log;
import android.util.SparseIntArray;
/** /**
* A {@link Service} that implements multi-client IME protocol. * A {@link Service} that implements multi-client IME protocol.
*/ */
public final class MultiClientInputMethod extends Service { public final class MultiClientInputMethod extends Service implements DisplayListener {
private static final String TAG = "MultiClientInputMethod"; private static final String TAG = "MultiClientInputMethod";
private static final boolean DEBUG = false; private static final boolean DEBUG = false;
// last client that had active InputConnection. // last client that had active InputConnection for a given displayId.
int mLastClientId = MultiClientInputMethodServiceDelegate.INVALID_CLIENT_ID; final SparseIntArray mDisplayToLastClientId = new SparseIntArray();
SoftInputWindowManager mSoftInputWindowManager; SoftInputWindowManager mSoftInputWindowManager;
MultiClientInputMethodServiceDelegate mDelegate; MultiClientInputMethodServiceDelegate mDelegate;
private DisplayManager mDisplayManager;
@Override @Override
public void onCreate() { public void onCreate() {
if (DEBUG) { if (DEBUG) {
@@ -72,11 +77,26 @@ public final class MultiClientInputMethod extends Service {
mSoftInputWindowManager = new SoftInputWindowManager(this, mDelegate); mSoftInputWindowManager = new SoftInputWindowManager(this, mDelegate);
} }
@Override
public void onDisplayAdded(int displayId) {
}
@Override
public void onDisplayRemoved(int displayId) {
mDisplayToLastClientId.delete(displayId);
}
@Override
public void onDisplayChanged(int displayId) {
}
@Override @Override
public IBinder onBind(Intent intent) { public IBinder onBind(Intent intent) {
if (DEBUG) { if (DEBUG) {
Log.v(TAG, "onBind intent=" + intent); Log.v(TAG, "onBind intent=" + intent);
} }
mDisplayManager = getApplicationContext().getSystemService(DisplayManager.class);
mDisplayManager.registerDisplayListener(this, getMainThreadHandler());
return mDelegate.onBind(intent); return mDelegate.onBind(intent);
} }
@@ -85,6 +105,9 @@ public final class MultiClientInputMethod extends Service {
if (DEBUG) { if (DEBUG) {
Log.v(TAG, "onUnbind intent=" + intent); Log.v(TAG, "onUnbind intent=" + intent);
} }
if (mDisplayManager != null) {
mDisplayManager.unregisterDisplayListener(this);
}
return mDelegate.onUnbind(intent); return mDelegate.onUnbind(intent);
} }