Much simpler means of tracking process status

This commit is contained in:
jdf
2010-02-27 14:17:54 +00:00
parent 5e075d4cec
commit 4d5624edac
3 changed files with 27 additions and 118 deletions
@@ -1,14 +1,10 @@
package processing.app.tools.android;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.concurrent.ConcurrentHashMap;
import java.util.regex.Pattern;
import processing.app.debug.RunnerListener;
import processing.app.tools.android.LogEntry.Severity;
@@ -16,10 +12,8 @@ import processing.app.tools.android.LogEntry.Severity;
public class AndroidDevice implements AndroidDeviceProperties {
private final AndroidEnvironment env;
private final String id;
private final AndroidProcesses processes;
private final Map<String, List<ProcessOutputListener>> outputListeners = new HashMap<String, List<ProcessOutputListener>>();
private final PropertyChangeSupport pcs = new PropertyChangeSupport(this);
private final Map<String, List<ProcessOutputListener>> outputListeners = new ConcurrentHashMap<String, List<ProcessOutputListener>>();
private final Map<Integer, String> pidToProcessName = new ConcurrentHashMap<Integer, String>();
// mutable state
private Process logcat;
@@ -27,7 +21,6 @@ public class AndroidDevice implements AndroidDeviceProperties {
public AndroidDevice(final AndroidEnvironment env, final String id) {
this.env = env;
this.id = id;
this.processes = new AndroidProcesses(this);
}
public void bringLauncherToFront() {
@@ -106,7 +99,6 @@ public class AndroidDevice implements AndroidDeviceProperties {
final String msg = entry.message;
final Severity sev = entry.severity;
if (src.equals("ActivityManager") && msg.startsWith("Start proc")) {
handleStartProcEntry(entry);
} else {
if ((src.equals("AndroidRuntime") && sev == Severity.Error)
|| src.equals("System.out") || src.equals("System.err")) {
@@ -128,7 +120,6 @@ public class AndroidDevice implements AndroidDeviceProperties {
}
public void initialize() throws IOException, InterruptedException {
processes.refresh();
new ProcessHelper(generateAdbCommand("logcat", "-c")).execute();
logcat = Runtime.getRuntime().exec(generateAdbCommand("logcat"));
new StreamPump(logcat.getInputStream()).addTarget(new LogLineProcessor())
@@ -137,10 +128,6 @@ public class AndroidDevice implements AndroidDeviceProperties {
}
public void shutdown() {
for (final PropertyChangeListener pcl : Arrays.asList(pcs
.getPropertyChangeListeners())) {
pcs.removePropertyChangeListener(pcl);
}
outputListeners.clear();
if (logcat != null) {
logcat.destroy();
@@ -156,10 +143,6 @@ public class AndroidDevice implements AndroidDeviceProperties {
return env;
}
public List<AndroidProcess> ps() {
return processes.getProcesses();
}
public void addOutputListener(final String processName,
final ProcessOutputListener listener) {
if (!outputListeners.containsKey(processName)) {
@@ -181,38 +164,19 @@ public class AndroidDevice implements AndroidDeviceProperties {
.compile("^Start proc (\\S+) for \\S+ [^:]+: pid=(\\d+).+$");
protected List<ProcessOutputListener> getListeners(final String pid) {
final AndroidProcess process = processes.byPid(pid);
if (process == null) {
final String processName = pidToProcessName.get(pid);
if (processName == null) {
return null;
}
return outputListeners.get(process.name);
}
private void handleStartProcEntry(final LogEntry entry) {
final Matcher m = START_PROC.matcher(entry.message);
if (m.matches()) {
startProc(m.group(1), m.group(2));
} else {
System.err.println("I don't recognize this start proc message:\n"
+ entry.message);
}
return outputListeners.get(processName);
}
private void startProc(final String name, final String pid) {
final AndroidProcess proc = new AndroidProcess(pid, name);
processes.refresh();
firePropertyChange(APP_STARTED, null, proc);
pidToProcessName.put(Integer.valueOf(pid), name);
}
private void endProc(final String pid) {
final AndroidProcess proc = processes.byPid(pid);
if (proc == null) {
System.err.println("Process " + pid
+ " ended, but I hadn't known about it.");
} else {
processes.refresh();
firePropertyChange(APP_ENDED, proc, null);
}
pidToProcessName.remove(Integer.valueOf(pid));
}
String[] generateAdbCommand(final String... cmd) {
@@ -229,17 +193,4 @@ public class AndroidDevice implements AndroidDeviceProperties {
return "[AndroidDevice " + getId() + "]";
}
public void addPropertyChangeListener(final PropertyChangeListener listener) {
pcs.addPropertyChangeListener(listener);
}
private void firePropertyChange(final String propertyName,
final Object oldValue, final Object newValue) {
pcs.firePropertyChange(propertyName, oldValue, newValue);
}
public void removePropertyChangeListener(final PropertyChangeListener listener) {
pcs.removePropertyChangeListener(listener);
}
}
@@ -1,59 +0,0 @@
package processing.app.tools.android;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class AndroidProcesses {
private final List<AndroidProcess> processes = new ArrayList<AndroidProcess>();
private final AndroidDevice device;
public AndroidProcesses(final AndroidDevice device) {
this.device = device;
}
void refresh() {
processes.clear();
try {
for (final String line : new ProcessHelper(this.device
.generateAdbCommand("shell", "ps")).execute()) {
final String[] fields = line.split("\\s+");
if (fields.length != 9 || fields[0].equals("USER")) {
continue;
}
final String pid = fields[1];
final String name = fields[8];
processes.add(new AndroidProcess(pid, name));
}
} catch (final Exception e) {
System.err.println("Unable to refresh processes on " + device + ":");
e.printStackTrace(System.err);
}
}
List<AndroidProcess> getProcesses() {
return Collections.unmodifiableList(processes);
}
public AndroidProcess byPid(final String pid) {
for (final AndroidProcess p : processes) {
if (p.pid.equals(pid)) {
return p;
}
}
return null;
}
public AndroidProcess byName(final String name) {
for (final AndroidProcess p : processes) {
if (p.name.equals(name)) {
return p;
}
}
return null;
}
public void add(final AndroidProcess androidProcess) {
processes.add(androidProcess);
}
}