Merge "Create display context when switching IME to new display"
diff --git a/samples/MultiClientInputMethod/src/com/example/android/multiclientinputmethod/ClientCallbackImpl.java b/samples/MultiClientInputMethod/src/com/example/android/multiclientinputmethod/ClientCallbackImpl.java
index cf805bf..6f5d89d 100644
--- a/samples/MultiClientInputMethod/src/com/example/android/multiclientinputmethod/ClientCallbackImpl.java
+++ b/samples/MultiClientInputMethod/src/com/example/android/multiclientinputmethod/ClientCallbackImpl.java
@@ -58,7 +58,7 @@
         // 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
         // and introduce an appropriate synchronization mechanism instead of directly accessing
-        // MultiClientInputMethod#mLastClientId.
+        // MultiClientInputMethod#mDisplayToLastClientId.
         mLooper = Looper.getMainLooper();
     }
 
@@ -157,11 +157,13 @@
             mDelegate.reportImeWindowTarget(
                     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) {
-            // deactivate previous client.
-            if (mInputMethod.mLastClientId != mClientId) {
-                mDelegate.setActive(mInputMethod.mLastClientId, false /* active */);
-            }
             // Dummy InputConnection case.
             if (window.getClientId() == mClientId) {
                 // Special hack for temporary focus changes (e.g. notification shade).
@@ -171,9 +173,6 @@
                 window.onDummyStartInput(mClientId, targetWindowHandle);
             }
         } else {
-            if (mInputMethod.mLastClientId != mClientId) {
-                mDelegate.setActive(mClientId, true /* active */);
-            }
             window.onStartInput(mClientId, targetWindowHandle, inputConnection);
         }
 
@@ -195,7 +194,7 @@
                 window.hide();
                 break;
         }
-        mInputMethod.mLastClientId = mClientId;
+        mInputMethod.mDisplayToLastClientId.put(mSelfReportedDisplayId, mClientId);
     }
 
     @Override
diff --git a/samples/MultiClientInputMethod/src/com/example/android/multiclientinputmethod/MultiClientInputMethod.java b/samples/MultiClientInputMethod/src/com/example/android/multiclientinputmethod/MultiClientInputMethod.java
index 5beee7e..0b146ad 100644
--- a/samples/MultiClientInputMethod/src/com/example/android/multiclientinputmethod/MultiClientInputMethod.java
+++ b/samples/MultiClientInputMethod/src/com/example/android/multiclientinputmethod/MultiClientInputMethod.java
@@ -18,22 +18,27 @@
 
 import android.app.Service;
 import android.content.Intent;
+import android.hardware.display.DisplayManager;
+import android.hardware.display.DisplayManager.DisplayListener;
 import android.inputmethodservice.MultiClientInputMethodServiceDelegate;
 import android.os.IBinder;
 import android.util.Log;
+import android.util.SparseIntArray;
 
 /**
  * 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 boolean DEBUG = false;
 
-    // last client that had active InputConnection.
-    int mLastClientId = MultiClientInputMethodServiceDelegate.INVALID_CLIENT_ID;
+    // last client that had active InputConnection for a given displayId.
+    final SparseIntArray mDisplayToLastClientId = new SparseIntArray();
     SoftInputWindowManager mSoftInputWindowManager;
     MultiClientInputMethodServiceDelegate mDelegate;
 
+    private DisplayManager mDisplayManager;
+
     @Override
     public void onCreate() {
         if (DEBUG) {
@@ -73,10 +78,25 @@
     }
 
     @Override
+    public void onDisplayAdded(int displayId) {
+    }
+
+    @Override
+    public void onDisplayRemoved(int displayId) {
+        mDisplayToLastClientId.delete(displayId);
+    }
+
+    @Override
+    public void onDisplayChanged(int displayId) {
+    }
+
+    @Override
     public IBinder onBind(Intent intent) {
         if (DEBUG) {
             Log.v(TAG, "onBind intent=" + intent);
         }
+        mDisplayManager = getApplicationContext().getSystemService(DisplayManager.class);
+        mDisplayManager.registerDisplayListener(this, getMainThreadHandler());
         return mDelegate.onBind(intent);
     }
 
@@ -85,6 +105,9 @@
         if (DEBUG) {
             Log.v(TAG, "onUnbind intent=" + intent);
         }
+        if (mDisplayManager != null) {
+            mDisplayManager.unregisterDisplayListener(this);
+        }
         return mDelegate.onUnbind(intent);
     }