Methods Summary |
---|
public void | addOutput(byte[] data, int offset, int length)Adds output to the temp file. IShellOutputReceiver method. Called by
executeShellCommand().
try {
mTempStream.write(data, offset, length);
}
catch (IOException e) {
Log.e("DDMS", e);
}
|
public void | clientChanged(com.android.ddmlib.Client client, int changeMask)
// Don't care
|
public void | clientSelected()Sent when a new client is selected. The new client can be accessed with
{@link #getCurrentClient()}.
|
protected org.eclipse.swt.widgets.Control | createControl(org.eclipse.swt.widgets.Composite parent)Create our controls for the UI panel.
Composite top = new Composite(parent, SWT.NONE);
top.setLayout(new GridLayout(1, false));
top.setLayoutData(new GridData(GridData.FILL_BOTH));
Composite buttons = new Composite(top, SWT.NONE);
buttons.setLayout(new RowLayout());
mDisplayMode = new Combo(buttons, SWT.PUSH);
for (String mode : CAPTIONS) {
mDisplayMode.add(mode);
}
mDisplayMode.select(mMode);
mDisplayMode.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
mMode = mDisplayMode.getSelectionIndex();
if (mDataFile != null) {
generateDataset(mDataFile);
} else if (getCurrentDevice() != null) {
loadFromDevice();
}
}
});
final Button loadButton = new Button(buttons, SWT.PUSH);
loadButton.setText("Load from File");
loadButton.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
FileDialog fileDialog = new FileDialog(loadButton.getShell(),
SWT.OPEN);
fileDialog.setText("Load bugreport");
String filename = fileDialog.open();
if (filename != null) {
mDataFile = new File(filename);
generateDataset(mDataFile);
}
}
});
mFetchButton = new Button(buttons, SWT.PUSH);
mFetchButton.setText("Update from Device");
mFetchButton.setEnabled(false);
mFetchButton.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
loadFromDevice();
}
});
mLabel = new Label(top, SWT.NONE);
mLabel.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
mDataset = new DefaultPieDataset();
JFreeChart chart = ChartFactory.createPieChart("", mDataset, false
/* legend */, true/* tooltips */, false /* urls */);
ChartComposite chartComposite = new ChartComposite(top,
SWT.BORDER, chart,
ChartComposite.DEFAULT_HEIGHT,
ChartComposite.DEFAULT_HEIGHT,
ChartComposite.DEFAULT_MINIMUM_DRAW_WIDTH,
ChartComposite.DEFAULT_MINIMUM_DRAW_HEIGHT,
3000,
// max draw width. We don't want it to zoom, so we put a big number
3000,
// max draw height. We don't want it to zoom, so we put a big number
true, // off-screen buffer
true, // properties
true, // save
true, // print
false, // zoom
true);
chartComposite.setLayoutData(new GridData(GridData.FILL_BOTH));
return top;
|
public void | deviceSelected()Sent when a new device is selected. The new device can be accessed with
{@link #getCurrentDevice()}
if (getCurrentDevice() != null) {
mFetchButton.setEnabled(true);
loadFromDevice();
} else {
mFetchButton.setEnabled(false);
}
|
public void | flush()Processes output from shell command. IShellOutputReceiver method. The
output is passed to generateDataset(). Called by executeShellCommand() on
completion.
if (mTempStream != null) {
try {
mTempStream.close();
generateDataset(mDataFile);
mTempStream = null;
mDataFile = null;
} catch (IOException e) {
Log.e("DDMS", e);
}
}
|
public void | generateDataset(java.io.File file)Generates the dataset to display.
mDataset.clear();
mLabel.setText("");
if (file == null) {
return;
}
try {
BufferedReader br = getBugreportReader(file);
if (mMode == MODE_CPU) {
readCpuDataset(br);
} else if (mMode == MODE_ALARM) {
readAlarmDataset(br);
} else if (mMode == MODE_WAKELOCK) {
readWakelockDataset(br);
} else if (mMode == MODE_MEMINFO) {
readMeminfoDataset(br);
} else if (mMode == MODE_SYNC) {
readSyncDataset(br);
}
} catch (IOException e) {
Log.e("DDMS", e);
}
|
private java.io.BufferedReader | getBugreportReader(java.io.File file)Helper to open a bugreport and skip to the specified section.
BufferedReader br = new BufferedReader(new FileReader(file));
// Skip over the unwanted bugreport sections
while (true) {
String line = br.readLine();
if (line == null) {
Log.d("DDMS", "Service not found " + line);
break;
}
if ((line.startsWith("DUMP OF SERVICE ") || line.startsWith("-----")) &&
line.indexOf(BUGREPORT_SECTION[mMode]) > 0) {
break;
}
}
return br;
|
void | initShellOutputBuffer()Initializes temporary output file for executeShellCommand().
mDataFile = File.createTempFile("ddmsfile", ".txt");
mDataFile.deleteOnExit();
mTempStream = new FileOutputStream(mDataFile);
|
public boolean | isCancelled()IShellOutputReceiver method.
return false;
|
private void | loadFromDevice()Fetches a new bugreport from the device and updates the display.
Fetching is asynchronous. See also addOutput, flush, and isCancelled.
try {
initShellOutputBuffer();
if (mMode == MODE_MEMINFO) {
// Hack to add bugreport-style section header for meminfo
mTempStream.write("------ MEMORY INFO ------\n".getBytes());
}
getCurrentDevice().executeShellCommand(
DUMP_COMMAND[mMode], this);
} catch (IOException e) {
Log.e("DDMS", e);
}
|
private static long | parseTimeMs(java.lang.String s)Parse the time string generated by BatteryStats.
A typical new-format string is "11d 13h 45m 39s 999ms".
A typical old-format string is "12.3 sec".
long total = 0;
// Matches a single component e.g. "12.3 sec" or "45ms"
Pattern p = Pattern.compile("([\\d\\.]+)\\s*([a-z]+)");
Matcher m = p.matcher(s);
while (m.find()) {
String label = m.group(2);
if ("sec".equals(label)) {
// Backwards compatibility with old time format
total += (long) (Double.parseDouble(m.group(1)) * 1000);
continue;
}
long value = Integer.parseInt(m.group(1));
if ("d".equals(label)) {
total += value * 24 * 60 * 60 * 1000;
} else if ("h".equals(label)) {
total += value * 60 * 60 * 1000;
} else if ("m".equals(label)) {
total += value * 60 * 1000;
} else if ("s".equals(label)) {
total += value * 1000;
} else if ("ms".equals(label)) {
total += value;
}
}
return total;
|
void | readAlarmDataset(java.io.BufferedReader br)Processes alarm information from bugreport. Updates mDataset with the new
data.
Pattern pattern = Pattern
.compile("(\\d+) alarms: Intent .*\\.([^. ]+) flags");
while (true) {
String line = br.readLine();
if (line == null || line.startsWith("DUMP OF SERVICE")) {
// Done, or moved on to the next service
break;
}
Matcher m = pattern.matcher(line);
if (m.find()) {
long count = Long.parseLong(m.group(1));
String name = m.group(2);
mDataset.setValue(name, count);
}
}
|
void | readCpuDataset(java.io.BufferedReader br)Processes cpu load information from bugreport. Updates mDataset with the
new data.
Pattern pattern = Pattern
.compile("(\\S+): (\\S+)% = (.+)% user . (.+)% kernel");
while (true) {
String line = br.readLine();
if (line == null || line.startsWith("DUMP OF SERVICE")) {
// Done, or moved on to the next service
break;
}
if (line.startsWith("Load:")) {
mLabel.setText(line);
continue;
}
Matcher m = pattern.matcher(line);
if (m.find()) {
String name = m.group(1);
long both = Long.parseLong(m.group(2));
long user = Long.parseLong(m.group(3));
long kernel = Long.parseLong(m.group(4));
if ("TOTAL".equals(name)) {
if (both < 100) {
mDataset.setValue("Idle", (100 - both));
}
} else {
// Try to make graphs more useful even with rounding;
// log often has 0% user + 0% kernel = 1% total
// We arbitrarily give extra to kernel
if (user > 0) {
mDataset.setValue(name + " (user)", user);
}
if (kernel > 0) {
mDataset.setValue(name + " (kernel)" , both - user);
}
if (user == 0 && kernel == 0 && both > 0) {
mDataset.setValue(name, both);
}
}
}
}
|
void | readMeminfoDataset(java.io.BufferedReader br)Processes meminfo information from bugreport. Updates mDataset with the
new data.
Pattern valuePattern = Pattern.compile("(\\d+) kB");
long total = 0;
long other = 0;
mLabel.setText("PSS in kB");
// Scan meminfo
while (true) {
String line = br.readLine();
if (line == null) {
// End of file
break;
}
Matcher m = valuePattern.matcher(line);
if (m.find()) {
long kb = Long.parseLong(m.group(1));
if (line.startsWith("MemTotal")) {
total = kb;
} else if (line.startsWith("MemFree")) {
mDataset.setValue("Free", kb);
total -= kb;
} else if (line.startsWith("Slab")) {
mDataset.setValue("Slab", kb);
total -= kb;
} else if (line.startsWith("PageTables")) {
mDataset.setValue("PageTables", kb);
total -= kb;
} else if (line.startsWith("Buffers") && kb > 0) {
mDataset.setValue("Buffers", kb);
total -= kb;
} else if (line.startsWith("Inactive")) {
mDataset.setValue("Inactive", kb);
total -= kb;
} else if (line.startsWith("MemFree")) {
mDataset.setValue("Free", kb);
total -= kb;
}
} else {
break;
}
}
// Scan procrank
while (true) {
String line = br.readLine();
if (line == null) {
break;
}
if (line.indexOf("PROCRANK") >= 0 || line.indexOf("PID") >= 0) {
// procrank header
continue;
}
if (line.indexOf("----") >= 0) {
//end of procrank section
break;
}
// Extract pss field from procrank output
long pss = Long.parseLong(line.substring(23, 31).trim());
String cmdline = line.substring(43).trim().replace("/system/bin/", "");
// Arbitrary minimum size to display
if (pss > 2000) {
mDataset.setValue(cmdline, pss);
} else {
other += pss;
}
total -= pss;
}
mDataset.setValue("Other", other);
mDataset.setValue("Unknown", total);
|
void | readSyncDataset(java.io.BufferedReader br)Processes sync information from bugreport. Updates mDataset with the new
data.
while (true) {
String line = br.readLine();
if (line == null || line.startsWith("DUMP OF SERVICE")) {
// Done, or moved on to the next service
break;
}
if (line.startsWith(" |") && line.length() > 70) {
String authority = line.substring(3, 18).trim();
String duration = line.substring(61, 70).trim();
// Duration is MM:SS or HH:MM:SS (DateUtils.formatElapsedTime)
String durParts[] = duration.split(":");
if (durParts.length == 2) {
long dur = Long.parseLong(durParts[0]) * 60 + Long
.parseLong(durParts[1]);
mDataset.setValue(authority, dur);
} else if (duration.length() == 3) {
long dur = Long.parseLong(durParts[0]) * 3600
+ Long.parseLong(durParts[1]) * 60 + Long
.parseLong(durParts[2]);
mDataset.setValue(authority, dur);
}
}
}
|
void | readWakelockDataset(java.io.BufferedReader br)Processes wakelock information from bugreport. Updates mDataset with the
new data.
Pattern lockPattern = Pattern.compile("Wake lock (\\S+): (.+) partial");
Pattern totalPattern = Pattern.compile("Total: (.+) uptime");
double total = 0;
boolean inCurrent = false;
while (true) {
String line = br.readLine();
if (line == null || line.startsWith("DUMP OF SERVICE")) {
// Done, or moved on to the next service
break;
}
if (line.startsWith("Current Battery Usage Statistics")) {
inCurrent = true;
} else if (inCurrent) {
Matcher m = lockPattern.matcher(line);
if (m.find()) {
double value = parseTimeMs(m.group(2)) / 1000.;
mDataset.setValue(m.group(1), value);
total -= value;
} else {
m = totalPattern.matcher(line);
if (m.find()) {
total += parseTimeMs(m.group(1)) / 1000.;
}
}
}
}
if (total > 0) {
mDataset.setValue("Unlocked", total);
}
|
public void | setFocus()Sets the focus to the proper control inside the panel.
mDisplayMode.setFocus();
|