Merge "Making sure that the list of windows updates automatically in hierarchy viewer (View Server side)" into gingerbread
This commit is contained in:
committed by
Android (Google) Code Review
commit
c1ca7f8c53
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user