FileDocCategorySizeDatePackage
AllocationPanel.javaAPI DocAndroid 1.5 API18317Wed May 06 22:41:08 BST 2009com.android.ddmuilib

AllocationPanel

public class AllocationPanel extends TablePanel
Base class for our information panels.

Fields Summary
private static final String
PREFS_ALLOC_COL_SIZE
private static final String
PREFS_ALLOC_COL_CLASS
private static final String
PREFS_ALLOC_COL_THREAD
private static final String
PREFS_ALLOC_COL_TRACE_CLASS
private static final String
PREFS_ALLOC_COL_TRACE_METHOD
private static final String
PREFS_ALLOC_SASH
private static final String
PREFS_STACK_COL_CLASS
private static final String
PREFS_STACK_COL_METHOD
private static final String
PREFS_STACK_COL_FILE
private static final String
PREFS_STACK_COL_LINE
private static final String
PREFS_STACK_COL_NATIVE
private org.eclipse.swt.widgets.Composite
mAllocationBase
private org.eclipse.swt.widgets.Table
mAllocationTable
private org.eclipse.jface.viewers.TableViewer
mAllocationViewer
private StackTracePanel
mStackTracePanel
private org.eclipse.swt.widgets.Table
mStackTraceTable
private org.eclipse.swt.widgets.Button
mEnableButton
private org.eclipse.swt.widgets.Button
mRequestButton
Constructors Summary
Methods Summary
public voidclientChanged(com.android.ddmlib.Client client, int changeMask)
Sent when an existing client information changed.

This is sent from a non UI thread.

param
client the updated client.
param
changeMask the bit mask describing the changed properties. It can contain any of the following values: {@link Client#CHANGE_INFO}, {@link Client#CHANGE_NAME} {@link Client#CHANGE_DEBUGGER_INTEREST}, {@link Client#CHANGE_THREAD_MODE}, {@link Client#CHANGE_THREAD_DATA}, {@link Client#CHANGE_HEAP_MODE}, {@link Client#CHANGE_HEAP_DATA}, {@link Client#CHANGE_NATIVE_HEAP_DATA}
see
IClientChangeListener#clientChanged(Client, int)

        if (client == getCurrentClient()) {
            if ((changeMask & Client.CHANGE_HEAP_ALLOCATIONS) != 0) {
                try {
                    mAllocationTable.getDisplay().asyncExec(new Runnable() {
                        public void run() {
                            mAllocationViewer.refresh();
                            updateAllocationStackCall();
                        }
                    });
                } catch (SWTException e) {
                    // widget is disposed, we do nothing
                }
            } else if ((changeMask & Client.CHANGE_HEAP_ALLOCATION_STATUS) != 0) {
                try {
                    mAllocationTable.getDisplay().asyncExec(new Runnable() {
                        public void run() {
                            setUpButtons(true, client.getClientData().getAllocationStatus());
                        }
                    });
                } catch (SWTException e) {
                    // widget is disposed, we do nothing
                }
            }
        }
    
public voidclientSelected()
Sent when a new client is selected. The new client can be accessed with {@link #getCurrentClient()}.

        if (mAllocationTable.isDisposed()) {
            return;
        }

        Client client = getCurrentClient();
        
        mStackTracePanel.setCurrentClient(client);
        mStackTracePanel.setViewerInput(null); // always empty on client selection change.

        if (client != null) {
            setUpButtons(true /* enabled */, client.getClientData().getAllocationStatus());
        } else {
            setUpButtons(false /* enabled */,
                    ClientData.ALLOCATION_TRACKING_OFF /* trackingStatus */);
        }

        mAllocationViewer.setInput(client);
    
protected org.eclipse.swt.widgets.ControlcreateControl(org.eclipse.swt.widgets.Composite parent)
Create our control(s).

        final IPreferenceStore store = DdmUiPreferences.getStore();

        // base composite for selected client with enabled thread update.
        mAllocationBase = new Composite(parent, SWT.NONE);
        mAllocationBase.setLayout(new FormLayout());
        
        // table above the sash
        Composite topParent = new Composite(mAllocationBase, SWT.NONE);
        topParent.setLayout(new GridLayout(2, false));
        
        mEnableButton = new Button(topParent, SWT.PUSH);
        mEnableButton.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                Client current = getCurrentClient();
                int status = current.getClientData().getAllocationStatus();
                if (status == ClientData.ALLOCATION_TRACKING_ON) {
                    current.enableAllocationTracker(false);
                } else {
                    current.enableAllocationTracker(true);
                }
                current.requestAllocationStatus();
            }
        });

        mRequestButton = new Button(topParent, SWT.PUSH);
        mRequestButton.setText("Get Allocations");
        mRequestButton.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                getCurrentClient().requestAllocationDetails();
            }
        });
        
        setUpButtons(false /* enabled */, ClientData.ALLOCATION_TRACKING_OFF /* trackingStatus */);

        mAllocationTable = new Table(topParent, SWT.MULTI | SWT.FULL_SELECTION);
        GridData gridData;
        mAllocationTable.setLayoutData(gridData = new GridData(GridData.FILL_BOTH));
        gridData.horizontalSpan = 2;
        mAllocationTable.setHeaderVisible(true);
        mAllocationTable.setLinesVisible(true);

        TableHelper.createTableColumn(
                mAllocationTable,
                "Allocation Size",
                SWT.RIGHT,
                "888", //$NON-NLS-1$
                PREFS_ALLOC_COL_SIZE, store);

        TableHelper.createTableColumn(
                mAllocationTable,
                "Allocated Class",
                SWT.LEFT,
                "Allocated Class", //$NON-NLS-1$
                PREFS_ALLOC_COL_CLASS, store);

        TableHelper.createTableColumn(
                mAllocationTable,
                "Thread Id",
                SWT.LEFT,
                "999", //$NON-NLS-1$
                PREFS_ALLOC_COL_THREAD, store);

        TableHelper.createTableColumn(
                mAllocationTable,
                "Allocated in",
                SWT.LEFT,
                "utime", //$NON-NLS-1$
                PREFS_ALLOC_COL_TRACE_CLASS, store);

        TableHelper.createTableColumn(
                mAllocationTable,
                "Allocated in",
                SWT.LEFT,
                "utime", //$NON-NLS-1$
                PREFS_ALLOC_COL_TRACE_METHOD, store);
        
        mAllocationViewer = new TableViewer(mAllocationTable);
        mAllocationViewer.setContentProvider(new AllocationContentProvider());
        mAllocationViewer.setLabelProvider(new AllocationLabelProvider());

        mAllocationViewer.addSelectionChangedListener(new ISelectionChangedListener() {
            public void selectionChanged(SelectionChangedEvent event) {
                AllocationInfo selectedAlloc = getAllocationSelection(event.getSelection());
                updateAllocationStackTrace(selectedAlloc);
            }
        });
        
        // the separating sash
        final Sash sash = new Sash(mAllocationBase, SWT.HORIZONTAL);
        Color darkGray = parent.getDisplay().getSystemColor(SWT.COLOR_DARK_GRAY);
        sash.setBackground(darkGray);
        
        // the UI below the sash
        mStackTracePanel = new StackTracePanel();
        mStackTraceTable = mStackTracePanel.createPanel(mAllocationBase,
                PREFS_STACK_COL_CLASS,
                PREFS_STACK_COL_METHOD,
                PREFS_STACK_COL_FILE,
                PREFS_STACK_COL_LINE,
                PREFS_STACK_COL_NATIVE,
                store);
        
        // now setup the sash.
        // form layout data
        FormData data = new FormData();
        data.top = new FormAttachment(0, 0);
        data.bottom = new FormAttachment(sash, 0);
        data.left = new FormAttachment(0, 0);
        data.right = new FormAttachment(100, 0);
        topParent.setLayoutData(data);

        final FormData sashData = new FormData();
        if (store != null && store.contains(PREFS_ALLOC_SASH)) {
            sashData.top = new FormAttachment(0, store.getInt(PREFS_ALLOC_SASH));
        } else {
            sashData.top = new FormAttachment(50,0); // 50% across
        }
        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.bottom = new FormAttachment(100, 0);
        data.left = new FormAttachment(0, 0);
        data.right = new FormAttachment(100, 0);
        mStackTraceTable.setLayoutData(data);

        // allow resizes, but cap at minPanelWidth
        sash.addListener(SWT.Selection, new Listener() {
            public void handleEvent(Event e) {
                Rectangle sashRect = sash.getBounds();
                Rectangle panelRect = mAllocationBase.getClientArea();
                int bottom = panelRect.height - sashRect.height - 100;
                e.y = Math.max(Math.min(e.y, bottom), 100);
                if (e.y != sashRect.y) {
                    sashData.top = new FormAttachment(0, e.y);
                    store.setValue(PREFS_ALLOC_SASH, e.y);
                    mAllocationBase.layout();
                }
            }
        });

        return mAllocationBase;
    
public voiddeviceSelected()
Sent when a new device is selected. The new device can be accessed with {@link #getCurrentDevice()}.

        // pass
    
private com.android.ddmlib.AllocationInfogetAllocationSelection(org.eclipse.jface.viewers.ISelection selection)
Returns the current allocation selection or null if none is found. If a {@link ISelection} object is specified, the first {@link AllocationInfo} from this selection is returned, otherwise, the ISelection returned by {@link TableViewer#getSelection()} is used.

param
selection the {@link ISelection} to use, or null

        if (selection == null) {
            selection = mAllocationViewer.getSelection();
        }
        
        if (selection instanceof IStructuredSelection) {
            IStructuredSelection structuredSelection = (IStructuredSelection)selection;
            Object object = structuredSelection.getFirstElement();
            if (object instanceof AllocationInfo) {
                return (AllocationInfo)object;
            }
        }
        
        return null;
    
public voidsetFocus()
Sets the focus to the proper control inside the panel.

        mAllocationTable.setFocus();
    
protected voidsetTableFocusListener()

        addTableToFocusListener(mAllocationTable);
        addTableToFocusListener(mStackTraceTable);
    
private voidsetUpButtons(boolean enabled, int trackingStatus)

param
enabled
param
trackingStatus

        if (enabled) {
            switch (trackingStatus) {
                case ClientData.ALLOCATION_TRACKING_UNKNOWN:
                    mEnableButton.setText("?");
                    mEnableButton.setEnabled(false);
                    mRequestButton.setEnabled(false);
                    break;
                case ClientData.ALLOCATION_TRACKING_OFF:
                    mEnableButton.setText("Start Tracking");
                    mEnableButton.setEnabled(true);
                    mRequestButton.setEnabled(false);
                    break;
                case ClientData.ALLOCATION_TRACKING_ON:
                    mEnableButton.setText("Stop Tracking");
                    mEnableButton.setEnabled(true);
                    mRequestButton.setEnabled(true);
                    break;
            }
        } else {
            mEnableButton.setEnabled(false);
            mRequestButton.setEnabled(false);
            mEnableButton.setText("Start Tracking");
        }
    
private voidupdateAllocationStackCall()
Updates the stack call of the currently selected thread.

This must be called from the UI thread.

        Client client = getCurrentClient();
        if (client != null) {
            // get the current selection in the ThreadTable
            AllocationInfo selectedAlloc = getAllocationSelection(null);
            
            if (selectedAlloc != null) {
                updateAllocationStackTrace(selectedAlloc);
            } else {
                updateAllocationStackTrace(null);
            }
        }
    
private voidupdateAllocationStackTrace(com.android.ddmlib.AllocationInfo alloc)
updates the stackcall of the specified allocation. If null the UI is emptied of current data.

param
thread

        mStackTracePanel.setViewerInput(alloc);