diff options
| author | 2010-07-08 17:55:51 -0700 | |
|---|---|---|
| committer | 2010-07-12 19:37:24 -0700 | |
| commit | dc30101ff86648c6665bf9d4579869f5badfc2f2 (patch) | |
| tree | 191a2ac7cb10c247451219f953897b0593e44086 | |
| parent | f6120cf431804e072f34699a5d8a3fae62492cee (diff) | |
Making sure that the list of windows updates automatically in hierarchy viewer (View Server side)
Change-Id: I0f49ee8b6950ad167bd224093150050e19fd1dd7
| -rw-r--r-- | services/java/com/android/server/ViewServer.java | 179 | ||||
| -rw-r--r-- | services/java/com/android/server/WindowManagerService.java | 64 |
2 files changed, 193 insertions, 50 deletions
diff --git a/services/java/com/android/server/ViewServer.java b/services/java/com/android/server/ViewServer.java index ae0043807284..9c7db9bc3cf4 100644 --- a/services/java/com/android/server/ViewServer.java +++ b/services/java/com/android/server/ViewServer.java @@ -21,6 +21,8 @@ import android.util.Slog; import java.net.ServerSocket; import java.net.Socket; import java.net.InetAddress; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; import java.io.IOException; import java.io.BufferedReader; import java.io.InputStreamReader; @@ -41,11 +43,13 @@ class ViewServer implements Runnable { */ public static final int VIEW_SERVER_DEFAULT_PORT = 4939; + private static final int VIEW_SERVER_MAX_CONNECTIONS = 10; + // Debug facility private static final String LOG_TAG = "ViewServer"; - private static final String VALUE_PROTOCOL_VERSION = "2"; - private static final String VALUE_SERVER_VERSION = "3"; + private static final String VALUE_PROTOCOL_VERSION = "3"; + private static final String VALUE_SERVER_VERSION = "4"; // Protocol commands // Returns the protocol version @@ -54,6 +58,8 @@ class ViewServer implements Runnable { private static final String COMMAND_SERVER_VERSION = "SERVER"; // Lists all of the available windows in the system private static final String COMMAND_WINDOW_MANAGER_LIST = "LIST"; + // Keeps a connection open and notifies when the list of windows changes + private static final String COMMAND_WINDOW_MANAGER_AUTOLIST = "AUTOLIST"; private ServerSocket mServer; private Thread mThread; @@ -61,6 +67,8 @@ class ViewServer implements Runnable { private final WindowManagerService mWindowManager; private final int mPort; + private ExecutorService mThreadPool; + /** * Creates a new ViewServer associated with the specified window manager. * The server uses the default port {@link #VIEW_SERVER_DEFAULT_PORT}. The server @@ -103,8 +111,9 @@ class ViewServer implements Runnable { return false; } - mServer = new ServerSocket(mPort, 1, InetAddress.getLocalHost()); + mServer = new ServerSocket(mPort, VIEW_SERVER_MAX_CONNECTIONS, InetAddress.getLocalHost()); mThread = new Thread(this, "Remote View Server [port=" + mPort + "]"); + mThreadPool = Executors.newFixedThreadPool(VIEW_SERVER_MAX_CONNECTIONS); mThread.start(); return true; @@ -122,7 +131,16 @@ class ViewServer implements Runnable { */ boolean stop() { if (mThread != null) { + mThread.interrupt(); + if (mThreadPool != null) { + try { + mThreadPool.shutdownNow(); + } catch (SecurityException e) { + Slog.w(LOG_TAG, "Could not stop all view server threads"); + } + } + mThreadPool = null; mThread = null; try { mServer.close(); @@ -152,62 +170,21 @@ class ViewServer implements Runnable { * Main server loop. */ public void run() { - final ServerSocket server = mServer; - while (Thread.currentThread() == mThread) { - Socket client = null; // Any uncaught exception will crash the system process try { - client = server.accept(); - - BufferedReader in = null; - try { - in = new BufferedReader(new InputStreamReader(client.getInputStream()), 1024); - - final String request = in.readLine(); - - String command; - String parameters; - - int index = request.indexOf(' '); - if (index == -1) { - command = request; - parameters = ""; - } else { - command = request.substring(0, index); - parameters = request.substring(index + 1); - } - - boolean result; - if (COMMAND_PROTOCOL_VERSION.equalsIgnoreCase(command)) { - result = writeValue(client, VALUE_PROTOCOL_VERSION); - } else if (COMMAND_SERVER_VERSION.equalsIgnoreCase(command)) { - result = writeValue(client, VALUE_SERVER_VERSION); - } else if (COMMAND_WINDOW_MANAGER_LIST.equalsIgnoreCase(command)) { - result = mWindowManager.viewServerListWindows(client); - } else { - result = mWindowManager.viewServerWindowCommand(client, - command, parameters); - } - - if (!result) { - Slog.w(LOG_TAG, "An error occured with the command: " + command); - } - } finally { - if (in != null) { - in.close(); - } - } - } catch (Exception e) { - Slog.w(LOG_TAG, "Connection error: ", e); - } finally { - if (client != null) { + Socket client = mServer.accept(); + if(mThreadPool != null) { + mThreadPool.submit(new ViewServerWorker(client)); + } else { try { client.close(); } catch (IOException e) { e.printStackTrace(); } } + } catch (Exception e) { + Slog.w(LOG_TAG, "Connection error: ", e); } } } @@ -235,4 +212,106 @@ class ViewServer implements Runnable { } return result; } + + class ViewServerWorker implements Runnable, WindowManagerService.WindowChangeListener { + private Socket mClient; + private boolean mNeedWindowListUpdate; + public ViewServerWorker(Socket client) { + mClient = client; + } + + public void run() { + + BufferedReader in = null; + try { + in = new BufferedReader(new InputStreamReader(mClient.getInputStream()), 1024); + + final String request = in.readLine(); + + String command; + String parameters; + + int index = request.indexOf(' '); + if (index == -1) { + command = request; + parameters = ""; + } else { + command = request.substring(0, index); + parameters = request.substring(index + 1); + } + + boolean result; + if (COMMAND_PROTOCOL_VERSION.equalsIgnoreCase(command)) { + result = writeValue(mClient, VALUE_PROTOCOL_VERSION); + } else if (COMMAND_SERVER_VERSION.equalsIgnoreCase(command)) { + result = writeValue(mClient, VALUE_SERVER_VERSION); + } else if (COMMAND_WINDOW_MANAGER_LIST.equalsIgnoreCase(command)) { + result = mWindowManager.viewServerListWindows(mClient); + } else if(COMMAND_WINDOW_MANAGER_AUTOLIST.equalsIgnoreCase(command)) { + result = windowManagerAutolistLoop(); + } else { + result = mWindowManager.viewServerWindowCommand(mClient, + command, parameters); + } + + if (!result) { + Slog.w(LOG_TAG, "An error occured with the command: " + command); + } + } catch(IOException e) { + Slog.w(LOG_TAG, "Connection error: ", e); + } finally { + if (in != null) { + try { + in.close(); + + } catch (IOException e) { + e.printStackTrace(); + } + } + if (mClient != null) { + try { + mClient.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + } + + public void windowsChanged() { + synchronized(this) { + mNeedWindowListUpdate = true; + notifyAll(); + } + } + + private boolean windowManagerAutolistLoop() { + mWindowManager.addWindowChangeListener(this); + BufferedWriter out = null; + try { + out = new BufferedWriter(new OutputStreamWriter(mClient.getOutputStream())); + while (!Thread.interrupted()) { + synchronized (this) { + while (!mNeedWindowListUpdate) { + wait(); + } + mNeedWindowListUpdate = false; + } + out.write("UPDATE\n"); + out.flush(); + } + } catch (Exception e) { + Slog.w(LOG_TAG, "Connection error: ", e); + } finally { + if (out != null) { + try { + out.close(); + } catch (IOException e) { + } + } + mWindowManager.removeWindowChangeListener(this); + } + return true; + } + } } diff --git a/services/java/com/android/server/WindowManagerService.java b/services/java/com/android/server/WindowManagerService.java index 38f1e1fb800f..833d08eaa507 100644 --- a/services/java/com/android/server/WindowManagerService.java +++ b/services/java/com/android/server/WindowManagerService.java @@ -489,6 +489,13 @@ public class WindowManagerService extends IWindowManager.Stub boolean mInTouchMode = false; private ViewServer mViewServer; + private ArrayList<WindowChangeListener> mWindowChangeListeners = + new ArrayList<WindowChangeListener>(); + private boolean mWindowsChanged = false; + + public interface WindowChangeListener { + public void windowsChanged(); + } final Configuration mTempConfiguration = new Configuration(); int mScreenLayout = Configuration.SCREENLAYOUT_SIZE_UNDEFINED; @@ -662,6 +669,7 @@ public class WindowManagerService extends IWindowManager.Stub TAG, "Adding window " + window + " at " + (i+1) + " of " + mWindows.size() + " (after " + pos + ")"); mWindows.add(i+1, window); + mWindowsChanged = true; } private void placeWindowBefore(Object pos, WindowState window) { @@ -670,6 +678,7 @@ public class WindowManagerService extends IWindowManager.Stub TAG, "Adding window " + window + " at " + i + " of " + mWindows.size() + " (before " + pos + ")"); mWindows.add(i, window); + mWindowsChanged = true; } //This method finds out the index of a window that has the same app token as @@ -727,6 +736,7 @@ public class WindowManagerService extends IWindowManager.Stub TAG, "Adding window " + win + " at " + (newIdx+1) + " of " + N); localmWindows.add(newIdx+1, win); + mWindowsChanged = true; } } } @@ -809,6 +819,7 @@ public class WindowManagerService extends IWindowManager.Stub TAG, "Adding window " + win + " at " + i + " of " + N); localmWindows.add(i, win); + mWindowsChanged = true; } } } @@ -826,6 +837,7 @@ public class WindowManagerService extends IWindowManager.Stub TAG, "Adding window " + win + " at " + i + " of " + N); localmWindows.add(i, win); + mWindowsChanged = true; } if (addToToken) { token.windows.add(tokenWindowsPos, win); @@ -1034,6 +1046,7 @@ public class WindowManagerService extends IWindowManager.Stub if (DEBUG_WINDOW_MOVEMENT) Slog.v( TAG, "Adding input method window " + win + " at " + pos); mWindows.add(pos, win); + mWindowsChanged = true; moveInputMethodDialogsLocked(pos+1); return; } @@ -1075,6 +1088,7 @@ public class WindowManagerService extends IWindowManager.Stub if (wpos < interestingPos) interestingPos--; if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Temp removing at " + wpos + ": " + win); mWindows.remove(wpos); + mWindowsChanged = true; int NC = win.mChildWindows.size(); while (NC > 0) { NC--; @@ -1101,6 +1115,7 @@ public class WindowManagerService extends IWindowManager.Stub if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "ReAdd removing from " + wpos + ": " + win); mWindows.remove(wpos); + mWindowsChanged = true; reAddWindowLocked(wpos, win); } } @@ -1561,6 +1576,7 @@ public class WindowManagerService extends IWindowManager.Stub if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Wallpaper removing at " + oldIndex + ": " + wallpaper); localmWindows.remove(oldIndex); + mWindowsChanged = true; if (oldIndex < foundI) { foundI--; } @@ -1572,6 +1588,7 @@ public class WindowManagerService extends IWindowManager.Stub + " from " + oldIndex + " to " + foundI); localmWindows.add(foundI, wallpaper); + mWindowsChanged = true; changed |= ADJUST_WALLPAPER_LAYERS_CHANGED; } } @@ -2078,6 +2095,7 @@ public class WindowManagerService extends IWindowManager.Stub mWindowMap.remove(win.mClient.asBinder()); mWindows.remove(win); + mWindowsChanged = true; if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Final remove of window: " + win); if (mInputMethodWindow == win) { @@ -3360,6 +3378,7 @@ public class WindowManagerService extends IWindowManager.Stub if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Removing starting window: " + startingWindow); mWindows.remove(startingWindow); + mWindowsChanged = true; ttoken.windows.remove(startingWindow); ttoken.allAppWindows.remove(startingWindow); addWindowToListInOrderLocked(startingWindow, true); @@ -3841,6 +3860,7 @@ public class WindowManagerService extends IWindowManager.Stub WindowState win = token.windows.get(i); if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Tmp removing app window " + win); mWindows.remove(win); + mWindowsChanged = true; int j = win.mChildWindows.size(); while (j > 0) { j--; @@ -3945,6 +3965,7 @@ public class WindowManagerService extends IWindowManager.Stub mWindows.add(index, win); index++; } + mWindowsChanged = true; return index; } @@ -4783,6 +4804,33 @@ public class WindowManagerService extends IWindowManager.Stub return success; } + public void addWindowChangeListener(WindowChangeListener listener) { + synchronized(mWindowMap) { + mWindowChangeListeners.add(listener); + } + } + + public void removeWindowChangeListener(WindowChangeListener listener) { + synchronized(mWindowMap) { + mWindowChangeListeners.remove(listener); + } + } + + private void notifyWindowsChanged() { + 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].windowsChanged(); + } + } + private WindowState findWindow(int hashCode) { if (hashCode == -1) { return getFocusedWindow(); @@ -7672,6 +7720,7 @@ public class WindowManagerService extends IWindowManager.Stub 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; private Session mLastReportedHold; @@ -8003,6 +8052,16 @@ public class WindowManagerService extends IWindowManager.Stub break; } + case WINDOWS_CHANGED: { + if (mWindowsChanged) { + synchronized (mWindowMap) { + mWindowsChanged = false; + } + notifyWindowsChanged(); + } + break; + } + } } } @@ -8087,6 +8146,7 @@ public class WindowManagerService extends IWindowManager.Stub WindowState w = (WindowState)mWindows.get(i); if (w.mAppToken != null) { WindowState win = (WindowState)mWindows.remove(i); + mWindowsChanged = true; if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Rebuild removing window: " + win); NW--; @@ -8222,6 +8282,10 @@ public class WindowManagerService extends IWindowManager.Stub requestAnimationLocked(0); } } + if (mWindowsChanged && !mWindowChangeListeners.isEmpty()) { + mH.removeMessages(H.WINDOWS_CHANGED); + mH.sendMessage(mH.obtainMessage(H.WINDOWS_CHANGED)); + } } catch (RuntimeException e) { mInLayout = false; Slog.e(TAG, "Unhandled exception while layout out windows", e); |