diff options
author | Siva Velusamy <vsiva@google.com> | 2011-09-20 12:18:54 -0700 |
---|---|---|
committer | Siva Velusamy <vsiva@google.com> | 2011-09-20 16:57:20 -0700 |
commit | 88ee5dd5573f9700f6d5983af524b8eaf82665be (patch) | |
tree | 25580fd5cf8a4867c2b4fecadf013d3887d5cd7f /ddms/libs/ddmuilib | |
parent | cef07a6a4e2e55743187afdfd8a4f647ab70581f (diff) | |
download | sdk-88ee5dd5573f9700f6d5983af524b8eaf82665be.zip sdk-88ee5dd5573f9700f6d5983af524b8eaf82665be.tar.gz sdk-88ee5dd5573f9700f6d5983af524b8eaf82665be.tar.bz2 |
New implementation of native heap - layout only.
Address resolution to symbols to come in future CL's.
Diffstat (limited to 'ddms/libs/ddmuilib')
-rw-r--r-- | ddms/libs/ddmuilib/src/com/android/ddmuilib/heap/NativeHeapContentProvider.java | 68 | ||||
-rw-r--r-- | ddms/libs/ddmuilib/src/com/android/ddmuilib/heap/NativeHeapLabelProvider.java | 65 | ||||
-rw-r--r-- | ddms/libs/ddmuilib/src/com/android/ddmuilib/heap/NativeHeapPanel.java | 509 | ||||
-rw-r--r-- | ddms/libs/ddmuilib/src/com/android/ddmuilib/heap/NativeStackContentProvider.java | 51 | ||||
-rw-r--r-- | ddms/libs/ddmuilib/src/images/diff.png | bin | 0 -> 213 bytes | |||
-rw-r--r-- | ddms/libs/ddmuilib/src/images/groupby.png | bin | 0 -> 413 bytes | |||
-rw-r--r-- | ddms/libs/ddmuilib/src/images/zygote.png | bin | 0 -> 345 bytes |
7 files changed, 693 insertions, 0 deletions
diff --git a/ddms/libs/ddmuilib/src/com/android/ddmuilib/heap/NativeHeapContentProvider.java b/ddms/libs/ddmuilib/src/com/android/ddmuilib/heap/NativeHeapContentProvider.java new file mode 100644 index 0000000..6e651b3 --- /dev/null +++ b/ddms/libs/ddmuilib/src/com/android/ddmuilib/heap/NativeHeapContentProvider.java @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.ddmuilib.heap; + +import org.eclipse.jface.viewers.ILazyTreeContentProvider; +import org.eclipse.jface.viewers.TreeViewer; +import org.eclipse.jface.viewers.Viewer; + +import java.util.List; + +/** + * Content Provider for the native heap tree viewer in {@link NativeHeapPanel}. + * It expects a list of {@link NativeAllocationInfo} objects as input. + */ +public final class NativeHeapContentProvider implements ILazyTreeContentProvider { + private TreeViewer mViewer; + private List<?> mCurrentAllocations; + + public NativeHeapContentProvider(TreeViewer viewer) { + mViewer = viewer; + } + + public void dispose() { + } + + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + mCurrentAllocations = (List <?>) newInput; + } + + public Object getParent(Object arg0) { + return null; + } + + public void updateChildCount(Object element, int currentChildCount) { + int childCount = 0; + + if (element == mCurrentAllocations) { // root element + childCount = mCurrentAllocations.size(); + } + + mViewer.setChildCount(element, childCount); + } + + public void updateElement(Object parent, int index) { + Object item = null; + + if (parent == mCurrentAllocations) { // root element + item = mCurrentAllocations.get(index); + } + + mViewer.replace(parent, index, item); + mViewer.setChildCount(item, 0); + } +} diff --git a/ddms/libs/ddmuilib/src/com/android/ddmuilib/heap/NativeHeapLabelProvider.java b/ddms/libs/ddmuilib/src/com/android/ddmuilib/heap/NativeHeapLabelProvider.java new file mode 100644 index 0000000..159f507 --- /dev/null +++ b/ddms/libs/ddmuilib/src/com/android/ddmuilib/heap/NativeHeapLabelProvider.java @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.ddmuilib.heap; + +import com.android.ddmlib.NativeAllocationInfo; +import com.android.ddmlib.NativeStackCallInfo; + +import org.eclipse.jface.viewers.ITableLabelProvider; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.swt.graphics.Image; + +/** + * A Label Provider for the Native Heap TreeViewer in {@link NativeHeapPanel}. + */ +public class NativeHeapLabelProvider extends LabelProvider implements ITableLabelProvider { + public Image getColumnImage(Object arg0, int arg1) { + return null; + } + + public String getColumnText(Object element, int index) { + if (!(element instanceof NativeAllocationInfo)) { + return null; + } + + NativeAllocationInfo info = (NativeAllocationInfo) element; + NativeStackCallInfo stackInfo = info.getRelevantStackCallInfo(); + + switch (index) { + case 0: + return Integer.toString(info.getSize() * info.getAllocationCount()); + case 1: + return Integer.toString(info.getAllocationCount()); + case 2: + return Integer.toString(info.getSize()); + case 3: + return stackInfo == null ? stackResolutionStatus(info) : stackInfo.getLibraryName(); + case 4: + return stackInfo == null ? stackResolutionStatus(info) : stackInfo.getMethodName(); + default: + return null; + } + } + + private String stackResolutionStatus(NativeAllocationInfo info) { + if (info.isStackCallResolved()) { + return "?"; // resolved and unknown + } else { + return ""; // still resolving.. + } + } +} diff --git a/ddms/libs/ddmuilib/src/com/android/ddmuilib/heap/NativeHeapPanel.java b/ddms/libs/ddmuilib/src/com/android/ddmuilib/heap/NativeHeapPanel.java new file mode 100644 index 0000000..1b25c96 --- /dev/null +++ b/ddms/libs/ddmuilib/src/com/android/ddmuilib/heap/NativeHeapPanel.java @@ -0,0 +1,509 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.ddmuilib.heap; + +import com.android.ddmlib.Client; +import com.android.ddmlib.NativeAllocationInfo; +import com.android.ddmuilib.BaseHeapPanel; +import com.android.ddmuilib.ImageLoader; +import com.android.ddmuilib.TableHelper; + +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.jface.viewers.TreeViewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.layout.FormAttachment; +import org.eclipse.swt.layout.FormData; +import org.eclipse.swt.layout.FormLayout; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Combo; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Sash; +import org.eclipse.swt.widgets.Text; +import org.eclipse.swt.widgets.ToolBar; +import org.eclipse.swt.widgets.ToolItem; +import org.eclipse.swt.widgets.Tree; + +import java.text.NumberFormat; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** Panel to display native heap information. */ +public class NativeHeapPanel extends BaseHeapPanel { + private static final String TOOLTIP_EXPORT_DATA = "Export Heap Data"; + private static final String TOOLTIP_ZYGOTE_ALLOCATIONS = "Show Zygote Allocations"; + private static final String TOOLTIP_DIFFS_ONLY = "Only show differences from previous snapshot"; + private static final String TOOLTIP_GROUPBY = "Group allocations by library."; + + private static final String EXPORT_DATA_IMAGE = "save.png"; + private static final String ZYGOTE_IMAGE = "zygote.png"; + private static final String DIFFS_ONLY_IMAGE = "diff.png"; + private static final String GROUPBY_IMAGE = "groupby.png"; + + private static final String SNAPSHOT_HEAP_BUTTON_TEXT = "Snapshot Current Native Heap Usage"; + private static final String SYMBOL_SEARCH_PATH_LABEL_TEXT = "Symbol Search Path:"; + private static final String SYMBOL_SEARCH_PATH_TEXT_MESSAGE = + "List of colon separated paths to search for symbol debug information. See tooltip for examples."; + private static final String SYMBOL_SEARCH_PATH_TOOLTIP_TEXT = + "Colon separated paths that contain unstripped libraries with debug symbols.\n" + + "e.g.: <android-src>/out/target/product/generic/symbols/system/lib:/path/to/my/app/obj/local/armeabi"; + + private static final NumberFormat NUMBER_FORMATTER = NumberFormat.getInstance(); + + private static final String PREFS_SASH_HEIGHT_PERCENT = "nativeheap.sash.percent"; + private IPreferenceStore mPrefStore; + + private List<List<NativeAllocationInfo>> mNativeHeapAllocations; + + private Button mSnapshotHeapButton; + private Text mSymbolSearchPathText; + private Combo mSnapshotIndexCombo; + private Label mMemoryAllocatedText; + + private Tree mDetailsTree; + private TreeViewer mDetailsTreeViewer; + + private Tree mStackTraceTree; + private TreeViewer mStackTraceTreeViewer; + + private ToolBar mDetailsToolBar; + private ToolItem mGroupByButton; + private ToolItem mDiffsOnlyButton; + private ToolItem mShowZygoteAllocationsButton; + private ToolItem mExportHeapDataButton; + + public NativeHeapPanel(IPreferenceStore prefStore) { + mPrefStore = prefStore; + mPrefStore.setDefault(PREFS_SASH_HEIGHT_PERCENT, 75); + + mNativeHeapAllocations = new ArrayList<List<NativeAllocationInfo>>(); + } + + /** {@inheritDoc} */ + public void clientChanged(Client client, int changeMask) { + if (client != getCurrentClient()) { + return; + } + + if ((changeMask & Client.CHANGE_NATIVE_HEAP_DATA) != Client.CHANGE_NATIVE_HEAP_DATA) { + return; + } + + List<NativeAllocationInfo> allocations = client.getClientData().getNativeAllocationList(); + if (allocations.size() == 0) { + return; + } + + // We need to clone this list since getClientData().getNativeAllocationList() clobbers + // the list on future updates + allocations = shallowCloneList(allocations); + + mNativeHeapAllocations.add(allocations); + updateDisplay(); + } + + private List<NativeAllocationInfo> shallowCloneList(List<NativeAllocationInfo> allocations) { + List<NativeAllocationInfo> clonedList = + new ArrayList<NativeAllocationInfo>(allocations.size()); + + for (NativeAllocationInfo i : allocations) { + clonedList.add(i); + } + + return clonedList; + } + + @Override + public void deviceSelected() { + // pass + } + + @Override + public void clientSelected() { + Client c = getCurrentClient(); + + mSnapshotHeapButton.setEnabled(c != null); + + mNativeHeapAllocations = new ArrayList<List<NativeAllocationInfo>>(); + if (c != null) { + List<NativeAllocationInfo> allocations = c.getClientData().getNativeAllocationList(); + if (allocations.size() > 0) { + mNativeHeapAllocations.add(allocations); + } + } + + updateDisplay(); + } + + private void updateDisplay() { + Display.getDefault().syncExec(new Runnable() { + public void run() { + updateSnapshotIndexCombo(); + + List<NativeAllocationInfo> lastHeapSnapshot = null; + if (mNativeHeapAllocations.size() > 0) { + lastHeapSnapshot = + mNativeHeapAllocations.get(mNativeHeapAllocations.size() - 1); + } + + displaySnapshot(lastHeapSnapshot); + } + }); + } + + private void displaySelectedSnapshot() { + Display.getDefault().syncExec(new Runnable() { + public void run() { + int idx = mSnapshotIndexCombo.getSelectionIndex(); + displaySnapshot(mNativeHeapAllocations.get(idx)); + } + }); + } + + private void displaySnapshot(List<NativeAllocationInfo> heapSnapshot) { + mDetailsTreeViewer.setInput(heapSnapshot); + + if (heapSnapshot != null) { + mMemoryAllocatedText.setText(formatMemorySize(getTotalMemory(heapSnapshot))); + mMemoryAllocatedText.pack(); + } else { + mMemoryAllocatedText.setText(""); + } + } + + private String formatMemorySize(long totalMemory) { + return NUMBER_FORMATTER.format(totalMemory) + " bytes"; + } + + private long getTotalMemory(List<NativeAllocationInfo> heapSnapshot) { + long total = 0; + + for (NativeAllocationInfo info : heapSnapshot) { + total += info.getAllocationCount() * info.getSize(); + } + + return total; + } + + private void updateSnapshotIndexCombo() { + List<String> items = new ArrayList<String>(); + + int numSnapshots = mNativeHeapAllocations.size(); + for (int i = 0; i < numSnapshots; i++) { + // offset indices by 1 so that users see index starting at 1 rather than 0 + items.add("Snapshot " + (i + 1)); + } + + mSnapshotIndexCombo.setItems(items.toArray(new String[0])); + + if (numSnapshots > 0) { + mSnapshotIndexCombo.setEnabled(true); + mSnapshotIndexCombo.select(numSnapshots - 1); + } else { + mSnapshotIndexCombo.setEnabled(false); + } + } + + @Override + protected Control createControl(Composite parent) { + parent.setLayout(new GridLayout(1, false)); + + Composite c = new Composite(parent, SWT.NONE); + c.setLayout(new GridLayout(1, false)); + c.setLayoutData(new GridData(GridData.FILL_BOTH)); + + createControlsSection(c); + createDetailsSection(c); + + // Initialize widget state based on whether a client + // is selected or not. + clientSelected(); + + return c; + } + + private void createControlsSection(Composite parent) { + Composite c = new Composite(parent, SWT.NONE); + c.setLayout(new GridLayout(3, false)); + c.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + + createGetHeapDataButton(c); + + Label l = new Label(c, SWT.SEPARATOR | SWT.VERTICAL); + l.setLayoutData(new GridData(GridData.FILL_VERTICAL)); + + createDisplaySection(c); + } + + private void createGetHeapDataButton(Composite parent) { + mSnapshotHeapButton = new Button(parent, SWT.BORDER | SWT.PUSH); + mSnapshotHeapButton.setText(SNAPSHOT_HEAP_BUTTON_TEXT); + mSnapshotHeapButton.setLayoutData(new GridData()); + + // disable by default, enabled only when a client is selected + mSnapshotHeapButton.setEnabled(false); + + mSnapshotHeapButton.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent evt) { + snapshotHeap(); + } + }); + } + + private void snapshotHeap() { + Client c = getCurrentClient(); + assert c != null : "Snapshot Heap could not have been enabled w/o a selected client."; + + // send an async request + c.requestNativeHeapInformation(); + } + + private void createDisplaySection(Composite parent) { + Composite c = new Composite(parent, SWT.NONE); + c.setLayout(new GridLayout(2, false)); + c.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + + // Create: Display: __________________ + createLabel(c, "Display:"); + mSnapshotIndexCombo = new Combo(c, SWT.NONE | SWT.READ_ONLY); + mSnapshotIndexCombo.setItems(new String[] {"No heap snapshots available."}); + mSnapshotIndexCombo.setEnabled(false); + mSnapshotIndexCombo.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent arg0) { + displaySelectedSnapshot(); + } + }); + + // Create: Memory Allocated (bytes): _________________ + createLabel(c, "Memory Allocated:"); + mMemoryAllocatedText = new Label(c, SWT.NONE); + GridData gd = new GridData(); + gd.widthHint = 100; + mMemoryAllocatedText.setLayoutData(gd); + + // Create: Search Path: __________________ + createLabel(c, SYMBOL_SEARCH_PATH_LABEL_TEXT); + mSymbolSearchPathText = new Text(c, SWT.BORDER); + mSymbolSearchPathText.setMessage(SYMBOL_SEARCH_PATH_TEXT_MESSAGE); + mSymbolSearchPathText.setToolTipText(SYMBOL_SEARCH_PATH_TOOLTIP_TEXT); + } + + private void createLabel(Composite parent, String text) { + Label l = new Label(parent, SWT.NONE); + l.setText(text); + GridData gd = new GridData(); + gd.horizontalAlignment = SWT.RIGHT; + l.setLayoutData(gd); + } + + /** + * Create the details section displaying the details table and the stack trace + * corresponding to the selection. + * + * The details is laid out like so: + * Details Toolbar + * Details Table + * ------------sash--- + * Stack Trace Label + * Stack Trace Text + * There is a sash in between the two sections, and we need to save/restore the sash + * preferences. Using FormLayout seems like the easiest solution here, but the layout + * code looks ugly as a result. + */ + private void createDetailsSection(Composite parent) { + final Composite c = new Composite(parent, SWT.NONE); + c.setLayout(new FormLayout()); + c.setLayoutData(new GridData(GridData.FILL_BOTH)); + + mDetailsToolBar = new ToolBar(c, SWT.FLAT | SWT.BORDER); + initializeDetailsToolBar(mDetailsToolBar); + + mDetailsTree = new Tree(c, SWT.VIRTUAL | SWT.BORDER); + initializeDetailsTree(mDetailsTree); + + final Sash sash = new Sash(c, SWT.HORIZONTAL | SWT.BORDER); + + Label stackTraceLabel = new Label(c, SWT.NONE); + stackTraceLabel.setText("Stack Trace:"); + + mStackTraceTree = new Tree(c, SWT.BORDER); + initializeStackTraceTree(mStackTraceTree); + + // layout the widgets created above + FormData data = new FormData(); + data.top = new FormAttachment(0, 0); + data.left = new FormAttachment(0, 0); + data.right = new FormAttachment(100, 0); + mDetailsToolBar.setLayoutData(data); + + data = new FormData(); + data.top = new FormAttachment(mDetailsToolBar, 0); + data.bottom = new FormAttachment(sash, 0); + data.left = new FormAttachment(0, 0); + data.right = new FormAttachment(100, 0); + mDetailsTree.setLayoutData(data); + + final FormData sashData = new FormData(); + sashData.top = new FormAttachment(mPrefStore.getInt(PREFS_SASH_HEIGHT_PERCENT), 0); + sashData.left = new FormAttachment(0, 0); + sashData.right = new FormAttachment(100, 0); + sash.setLayoutData(sashData); + + data = new FormData(); + data.top = new FormAttachment(sash, 0); + data.left = new FormAttachment(0, 0); + data.right = new FormAttachment(100, 0); + stackTraceLabel.setLayoutData(data); + + data = new FormData(); + data.top = new FormAttachment(stackTraceLabel, 0); + data.left = new FormAttachment(0, 0); + data.bottom = new FormAttachment(100, 0); + data.right = new FormAttachment(100, 0); + mStackTraceTree.setLayoutData(data); + + sash.addListener(SWT.Selection, new Listener() { + public void handleEvent(Event e) { + Rectangle sashRect = sash.getBounds(); + Rectangle panelRect = c.getClientArea(); + int sashPercent = sashRect.y * 100 / panelRect.height; + mPrefStore.setValue(PREFS_SASH_HEIGHT_PERCENT, sashPercent); + + sashData.top = new FormAttachment(0, e.y); + c.layout(); + } + }); + } + + private void initializeDetailsToolBar(ToolBar toolbar) { + mGroupByButton = new ToolItem(toolbar, SWT.CHECK); + mGroupByButton.setImage(ImageLoader.getDdmUiLibLoader().loadImage(GROUPBY_IMAGE, + toolbar.getDisplay())); + mGroupByButton.setToolTipText(TOOLTIP_GROUPBY); + + mDiffsOnlyButton = new ToolItem(toolbar, SWT.CHECK); + mDiffsOnlyButton.setImage(ImageLoader.getDdmUiLibLoader().loadImage(DIFFS_ONLY_IMAGE, + toolbar.getDisplay())); + mDiffsOnlyButton.setToolTipText(TOOLTIP_DIFFS_ONLY); + + mShowZygoteAllocationsButton = new ToolItem(toolbar, SWT.CHECK); + mShowZygoteAllocationsButton.setImage(ImageLoader.getDdmUiLibLoader().loadImage( + ZYGOTE_IMAGE, toolbar.getDisplay())); + mShowZygoteAllocationsButton.setToolTipText(TOOLTIP_ZYGOTE_ALLOCATIONS); + mShowZygoteAllocationsButton.setSelection(true); + + mExportHeapDataButton = new ToolItem(toolbar, SWT.PUSH); + mExportHeapDataButton.setImage(ImageLoader.getDdmUiLibLoader().loadImage( + EXPORT_DATA_IMAGE, toolbar.getDisplay())); + mExportHeapDataButton.setToolTipText(TOOLTIP_EXPORT_DATA); + + // disable all toolbar items until they implement the necessary features + mGroupByButton.setEnabled(false); + mDiffsOnlyButton.setEnabled(false); + mShowZygoteAllocationsButton.setEnabled(false); + mExportHeapDataButton.setEnabled(false); + } + + private void initializeDetailsTree(Tree tree) { + tree.setHeaderVisible(true); + tree.setLinesVisible(true); + + List<String> properties = Arrays.asList(new String[] { + "Total", + "Count", + "Size", + "Library", + "Method", + }); + + List<String> sampleValues = Arrays.asList(new String[] { + "123456789", + "123456789", + "123456789", + "/path/in/device/to/system/library.so", + "PossiblyLongDemangledMethodName", + }); + + for (int i = 0; i < properties.size(); i++) { + String p = properties.get(i); + String v = sampleValues.get(i); + TableHelper.createTreeColumn(tree, p, SWT.LEFT, v, getPref("details", p), mPrefStore); + } + + mDetailsTreeViewer = new TreeViewer(tree); + + mDetailsTreeViewer.setUseHashlookup(true); + mDetailsTreeViewer.setContentProvider(new NativeHeapContentProvider(mDetailsTreeViewer)); + mDetailsTreeViewer.setLabelProvider(new NativeHeapLabelProvider()); + + mDetailsTreeViewer.setInput(null); + } + + private void initializeStackTraceTree(Tree tree) { + tree.setHeaderVisible(true); + tree.setLinesVisible(true); + + List<String> properties = Arrays.asList(new String[] { + "Address", + "Library", + "Method", + "File", + "Line", + }); + + List<String> sampleValues = Arrays.asList(new String[] { + "0x1234_5678", + "/path/in/device/to/system/library.so", + "PossiblyLongDemangledMethodName", + "/android/out/prefix/in/home/directory/to/path/in/device/to/system/library.so", + "2000", + }); + + for (int i = 0; i < properties.size(); i++) { + String p = properties.get(i); + String v = sampleValues.get(i); + TableHelper.createTreeColumn(tree, p, SWT.LEFT, v, getPref("stack", p), mPrefStore); + } + + mStackTraceTreeViewer = new TreeViewer(tree); + + mStackTraceTreeViewer.setContentProvider(new NativeStackContentProvider()); + + mStackTraceTreeViewer.setInput(null); + } + + private String getPref(String prefix, String s) { + return "nativeheap.tree." + prefix + "." + s; + } + + @Override + public void setFocus() { + // TODO + } +} diff --git a/ddms/libs/ddmuilib/src/com/android/ddmuilib/heap/NativeStackContentProvider.java b/ddms/libs/ddmuilib/src/com/android/ddmuilib/heap/NativeStackContentProvider.java new file mode 100644 index 0000000..a83164b --- /dev/null +++ b/ddms/libs/ddmuilib/src/com/android/ddmuilib/heap/NativeStackContentProvider.java @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.ddmuilib.heap; + +import org.eclipse.jface.viewers.ITreeContentProvider; +import org.eclipse.jface.viewers.Viewer; + +import java.util.List; + +public class NativeStackContentProvider implements ITreeContentProvider { + public Object[] getElements(Object arg0) { + return null; + } + + public void dispose() { + } + + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + } + + public Object[] getChildren(Object parentElement) { + if (parentElement instanceof List<?>) { + List<?> stack = (List<?>) parentElement; + return stack.toArray(); + } + + return null; + } + + public Object getParent(Object element) { + return null; + } + + public boolean hasChildren(Object element) { + return false; + } +} diff --git a/ddms/libs/ddmuilib/src/images/diff.png b/ddms/libs/ddmuilib/src/images/diff.png Binary files differnew file mode 100644 index 0000000..bdd9e5c --- /dev/null +++ b/ddms/libs/ddmuilib/src/images/diff.png diff --git a/ddms/libs/ddmuilib/src/images/groupby.png b/ddms/libs/ddmuilib/src/images/groupby.png Binary files differnew file mode 100644 index 0000000..250b982 --- /dev/null +++ b/ddms/libs/ddmuilib/src/images/groupby.png diff --git a/ddms/libs/ddmuilib/src/images/zygote.png b/ddms/libs/ddmuilib/src/images/zygote.png Binary files differnew file mode 100644 index 0000000..5cbb1d2 --- /dev/null +++ b/ddms/libs/ddmuilib/src/images/zygote.png |