Add features to DisplayManager.

Added Surface.setDisplayId().
Added callbacks to DisplayManagerService.

Change-Id: Idd3f85f8ca1f1208962f1196efd6a3ab51c8c259
diff --git a/core/java/android/view/Surface.java b/core/java/android/view/Surface.java
index abab268..5f5d1f2 100644
--- a/core/java/android/view/Surface.java
+++ b/core/java/android/view/Surface.java
@@ -469,6 +469,8 @@
     public native   void setFlags(int flags, int mask);
     /** @hide */
     public native   void setWindowCrop(Rect crop);
+    /** @hide */
+    public native   void setDisplayId(int displayId);
 
 
    
diff --git a/core/jni/android_view_Surface.cpp b/core/jni/android_view_Surface.cpp
index 3cd28b1..3ad6406 100644
--- a/core/jni/android_view_Surface.cpp
+++ b/core/jni/android_view_Surface.cpp
@@ -717,6 +717,14 @@
     }
 }
 
+static void Surface_setDisplayId(JNIEnv* env, jobject thiz, jint displayId)
+{
+    const sp<SurfaceControl>& surface(getSurfaceControl(env, thiz));
+    if (surface == 0) return;
+
+    // TODO(mathias): Everything.
+}
+
 // ----------------------------------------------------------------------------
 
 static void Surface_copyFrom(
@@ -855,6 +863,7 @@
     {"writeToParcel",       "(Landroid/os/Parcel;I)V", (void*)Surface_writeToParcel },
     {"isConsumerRunningBehind", "()Z", (void*)Surface_isConsumerRunningBehind },
     {"setWindowCrop",       "(Landroid/graphics/Rect;)V", (void*)Surface_setWindowCrop },
+    {"setDisplayId",        "(I)V", (void*)Surface_setDisplayId },
 };
 
 void nativeClassInit(JNIEnv* env, jclass clazz)
diff --git a/services/java/com/android/server/display/DisplayManagerService.java b/services/java/com/android/server/display/DisplayManagerService.java
index b9c9ffd..468bf21 100644
--- a/services/java/com/android/server/display/DisplayManagerService.java
+++ b/services/java/com/android/server/display/DisplayManagerService.java
@@ -62,6 +62,9 @@
     /** All the DisplayInfos in the system indexed by deviceId */
     private final SparseArray<DisplayInfo> mDisplayInfos = new SparseArray<DisplayInfo>();
 
+    private final ArrayList<DisplayCallback> mCallbacks =
+            new ArrayList<DisplayManagerService.DisplayCallback>();
+
     public DisplayManagerService() {
         mHeadless = SystemProperties.get(SYSTEM_HEADLESS).equals("1");
         registerDefaultDisplayAdapter();
@@ -131,8 +134,20 @@
      * @param adapter The wrapper for information associated with the physical display.
      */
     public void registerDisplayAdapter(DisplayAdapter adapter) {
+
+        int displayId;
+        DisplayCallback[] callbacks;
+
         synchronized (mLock) {
-            int displayId = mDisplayIdSeq++;
+            displayId = mDisplayIdSeq;
+            do {
+                // Find the next unused displayId. (Pretend like it might ever wrap around).
+                mDisplayIdSeq++;
+                if (mDisplayIdSeq < 0) {
+                    mDisplayIdSeq = Display.DEFAULT_DISPLAY + 1;
+                }
+            } while (mDisplayInfos.get(mDisplayIdSeq) != null);
+
             adapter.setDisplayId(displayId);
 
             createDisplayInfoLocked(displayId, adapter);
@@ -142,6 +157,11 @@
             mLogicalToPhysicals.put(displayId, list);
 
             mDisplayAdapters.add(adapter);
+            callbacks = mCallbacks.toArray(new DisplayCallback[mCallbacks.size()]);
+        }
+
+        for (int i = callbacks.length - 1; i >= 0; i--) {
+            callbacks[i].displayAdded(displayId);
         }
 
         // TODO: Notify SurfaceFlinger of new addition.
@@ -188,7 +208,6 @@
                 list = new ArrayList<DisplayAdapter>();
                 mLogicalToPhysicals.put(displayId, list);
             }
-
             list.add(adapter);
             adapter.setDisplayId(displayId);
         }
@@ -219,6 +238,20 @@
         // TODO: Notify SurfaceFlinger of removal.
     }
 
+    public void registerDisplayCallback(final DisplayCallback callback) {
+        synchronized (mLock) {
+            if (!mCallbacks.contains(callback)) {
+                mCallbacks.add(callback);
+            }
+        }
+    }
+
+    public void unregisterDisplayCallback(final DisplayCallback callback) {
+        synchronized (mLock) {
+            mCallbacks.remove(callback);
+        }
+    }
+
     /**
      * Create a new logical DisplayInfo and fill it in with information from the physical display.
      * @param displayId The logical identifier.
@@ -288,11 +321,17 @@
 
         DisplayDeviceInfo info = new DisplayDeviceInfo();
         for (DisplayAdapter adapter : mDisplayAdapters) {
-            pw.println("Display for adapter " + adapter.getName());
+            pw.println("Display for adapter " + adapter.getName()
+                + " assigned to Display " + adapter.getDisplayId());
             DisplayDevice device = adapter.getDisplayDevice();
             pw.print("  ");
             device.getInfo(info);
             pw.println(info);
         }
     }
+
+    public interface DisplayCallback {
+        public void displayAdded(int displayId);
+        public void displayRemoved(int displayId);
+    }
 }
diff --git a/services/java/com/android/server/wm/WindowStateAnimator.java b/services/java/com/android/server/wm/WindowStateAnimator.java
index f1c69f2..d931426 100644
--- a/services/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/java/com/android/server/wm/WindowStateAnimator.java
@@ -474,6 +474,7 @@
         private final Point mSize = new Point();
         private final Rect mWindowCrop = new Rect();
         private boolean mShown = false;
+        private int mDisplayId;
         private String mName = "Not named";
 
         public SurfaceTrace(SurfaceSession s,
@@ -481,6 +482,7 @@
                        OutOfResourcesException {
             super(s, pid, displayId, w, h, format, flags);
             mSize.set(w, h);
+            mDisplayId = displayId;
             Slog.v(SURFACE_TAG, "ctor: " + this + ". Called by "
                     + Debug.getCallers(3));
         }
@@ -548,6 +550,13 @@
         }
 
         @Override
+        public void setDisplayId(int displayId) {
+            super.setDisplayId(displayId);
+            mDisplayId = displayId;
+            Slog.v(SURFACE_TAG, "setDisplayId: " + this + ". Called by " + Debug.getCallers(3));
+        }
+
+        @Override
         public void hide() {
             super.hide();
             mShown = false;
@@ -588,7 +597,7 @@
         @Override
         public String toString() {
             return "Surface " + Integer.toHexString(System.identityHashCode(this)) + " "
-                    + mName + ": shown=" + mShown + " layer=" + mLayer
+                    + mName + " (" + mDisplayId + "): shown=" + mShown + " layer=" + mLayer
                     + " alpha=" + mSurfaceTraceAlpha + " " + mPosition.x + "," + mPosition.y
                     + " " + mSize.x + "x" + mSize.y
                     + " crop=" + mWindowCrop.toShortString();