Adding focus change notification

Change-Id: I49709c97aaf63bcd44695d99c61dbbee228416f4
diff --git a/services/java/com/android/server/ViewServer.java b/services/java/com/android/server/ViewServer.java
index 9c7db9b..b369f71 100644
--- a/services/java/com/android/server/ViewServer.java
+++ b/services/java/com/android/server/ViewServer.java
@@ -216,8 +216,11 @@
     class ViewServerWorker implements Runnable, WindowManagerService.WindowChangeListener {
         private Socket mClient;
         private boolean mNeedWindowListUpdate;
+        private boolean mNeedFocusedWindowUpdate;
         public ViewServerWorker(Socket client) {
             mClient = client;
+            mNeedWindowListUpdate = false;
+            mNeedFocusedWindowUpdate = false;
         }
 
         public void run() {
@@ -285,20 +288,42 @@
             }
         }
 
+        public void focusChanged() {
+            synchronized(this) {
+                mNeedFocusedWindowUpdate = true;
+                notifyAll();
+            }
+        }
+
         private boolean windowManagerAutolistLoop() {
             mWindowManager.addWindowChangeListener(this);
             BufferedWriter out = null;
             try {
                 out = new BufferedWriter(new OutputStreamWriter(mClient.getOutputStream()));
                 while (!Thread.interrupted()) {
+                    boolean needWindowListUpdate = false;
+                    boolean needFocusedWindowUpdate = false;
                     synchronized (this) {
-                        while (!mNeedWindowListUpdate) {
+                        while (!mNeedWindowListUpdate && !mNeedFocusedWindowUpdate) {
                             wait();
                         }
-                        mNeedWindowListUpdate = false;
+                        if (mNeedWindowListUpdate) {
+                            mNeedWindowListUpdate = false;
+                            needWindowListUpdate = true;
+                        }
+                        if (mNeedFocusedWindowUpdate) {
+                            mNeedFocusedWindowUpdate = false;
+                            needFocusedWindowUpdate = true;
+                        }
                     }
-                    out.write("UPDATE\n");
-                    out.flush();
+                    if(needWindowListUpdate) {
+                        out.write("LIST UPDATE\n");
+                        out.flush();
+                    }
+                    if(needFocusedWindowUpdate) {
+                        out.write("FOCUS UPDATE\n");
+                        out.flush();
+                    }
                 }
             } catch (Exception e) {
                 Slog.w(LOG_TAG, "Connection error: ", e);
diff --git a/services/java/com/android/server/WindowManagerService.java b/services/java/com/android/server/WindowManagerService.java
index 833d08e..c6e5cd2 100644
--- a/services/java/com/android/server/WindowManagerService.java
+++ b/services/java/com/android/server/WindowManagerService.java
@@ -495,6 +495,7 @@
 
     public interface WindowChangeListener {
         public void windowsChanged();
+        public void focusChanged();
     }
 
     final Configuration mTempConfiguration = new Configuration();
@@ -4831,6 +4832,21 @@
         }
     }
 
+    private void notifyFocusChanged() {
+        WindowChangeListener[] windowChangeListeners;
+        synchronized(mWindowMap) {
+            if(mWindowChangeListeners.isEmpty()) {
+                return;
+            }
+            windowChangeListeners = new WindowChangeListener[mWindowChangeListeners.size()];
+            windowChangeListeners = mWindowChangeListeners.toArray(windowChangeListeners);
+        }
+        int N = windowChangeListeners.length;
+        for(int i = 0; i < N; i++) {
+            windowChangeListeners[i].focusChanged();
+        }
+    }
+
     private WindowState findWindow(int hashCode) {
         if (hashCode == -1) {
             return getFocusedWindow();
@@ -7720,7 +7736,7 @@
         public static final int ENABLE_SCREEN = 16;
         public static final int APP_FREEZE_TIMEOUT = 17;
         public static final int SEND_NEW_CONFIGURATION = 18;
-        public static final int WINDOWS_CHANGED = 19;
+        public static final int REPORT_WINDOWS_CHANGE = 19;
 
         private Session mLastReportedHold;
 
@@ -7772,6 +7788,7 @@
                                 // Ignore if process has died.
                             }
                         }
+                        notifyFocusChanged();
                     }
                 } break;
 
@@ -8052,7 +8069,7 @@
                     break;
                 }
 
-                case WINDOWS_CHANGED: {
+                case REPORT_WINDOWS_CHANGE: {
                     if (mWindowsChanged) {
                         synchronized (mWindowMap) {
                             mWindowsChanged = false;
@@ -8283,8 +8300,8 @@
                 }
             }
             if (mWindowsChanged && !mWindowChangeListeners.isEmpty()) {
-                mH.removeMessages(H.WINDOWS_CHANGED);
-                mH.sendMessage(mH.obtainMessage(H.WINDOWS_CHANGED));
+                mH.removeMessages(H.REPORT_WINDOWS_CHANGE);
+                mH.sendMessage(mH.obtainMessage(H.REPORT_WINDOWS_CHANGE));
             }
         } catch (RuntimeException e) {
             mInLayout = false;