Home | History | Annotate | Download | only in views
      1 /*
      2  * Copyright (C) 2008 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.ide.eclipse.ddms.views;
     18 
     19 import com.android.ddmlib.AndroidDebugBridge;
     20 import com.android.ddmlib.Client;
     21 import com.android.ddmlib.ClientData;
     22 import com.android.ddmlib.DdmPreferences;
     23 import com.android.ddmlib.IDevice;
     24 import com.android.ddmlib.SyncException;
     25 import com.android.ddmlib.SyncService;
     26 import com.android.ddmlib.TimeoutException;
     27 import com.android.ddmlib.AndroidDebugBridge.IClientChangeListener;
     28 import com.android.ddmlib.ClientData.IHprofDumpHandler;
     29 import com.android.ddmlib.ClientData.MethodProfilingStatus;
     30 import com.android.ddmlib.SyncService.ISyncProgressMonitor;
     31 import com.android.ddmuilib.DevicePanel;
     32 import com.android.ddmuilib.ImageLoader;
     33 import com.android.ddmuilib.ScreenShotDialog;
     34 import com.android.ddmuilib.SyncProgressHelper;
     35 import com.android.ddmuilib.DevicePanel.IUiSelectionListener;
     36 import com.android.ddmuilib.SyncProgressHelper.SyncRunnable;
     37 import com.android.ddmuilib.handler.BaseFileHandler;
     38 import com.android.ddmuilib.handler.MethodProfilingHandler;
     39 import com.android.ide.eclipse.ddms.DdmsPlugin;
     40 import com.android.ide.eclipse.ddms.IDebuggerConnector;
     41 import com.android.ide.eclipse.ddms.i18n.Messages;
     42 import com.android.ide.eclipse.ddms.preferences.PreferenceInitializer;
     43 
     44 import org.eclipse.core.filesystem.EFS;
     45 import org.eclipse.core.filesystem.IFileStore;
     46 import org.eclipse.core.resources.ResourcesPlugin;
     47 import org.eclipse.core.runtime.IAdaptable;
     48 import org.eclipse.core.runtime.Path;
     49 import org.eclipse.jface.action.Action;
     50 import org.eclipse.jface.action.IAction;
     51 import org.eclipse.jface.action.IMenuManager;
     52 import org.eclipse.jface.action.IToolBarManager;
     53 import org.eclipse.jface.action.Separator;
     54 import org.eclipse.jface.dialogs.MessageDialog;
     55 import org.eclipse.jface.preference.IPreferenceStore;
     56 import org.eclipse.jface.resource.ImageDescriptor;
     57 import org.eclipse.swt.widgets.Composite;
     58 import org.eclipse.swt.widgets.Display;
     59 import org.eclipse.swt.widgets.Shell;
     60 import org.eclipse.ui.IActionBars;
     61 import org.eclipse.ui.ISharedImages;
     62 import org.eclipse.ui.IWorkbench;
     63 import org.eclipse.ui.IWorkbenchPage;
     64 import org.eclipse.ui.IWorkbenchWindow;
     65 import org.eclipse.ui.PartInitException;
     66 import org.eclipse.ui.PlatformUI;
     67 import org.eclipse.ui.WorkbenchException;
     68 import org.eclipse.ui.ide.IDE;
     69 import org.eclipse.ui.part.ViewPart;
     70 
     71 import java.io.File;
     72 import java.io.IOException;
     73 
     74 public class DeviceView extends ViewPart implements IUiSelectionListener, IClientChangeListener {
     75 
     76     private final static boolean USE_SELECTED_DEBUG_PORT = true;
     77 
     78     public static final String ID = "com.android.ide.eclipse.ddms.views.DeviceView"; //$NON-NLS-1$
     79 
     80     private static DeviceView sThis;
     81 
     82     private Shell mParentShell;
     83     private DevicePanel mDeviceList;
     84 
     85     private Action mResetAdbAction;
     86     private Action mCaptureAction;
     87     private Action mUpdateThreadAction;
     88     private Action mUpdateHeapAction;
     89     private Action mGcAction;
     90     private Action mKillAppAction;
     91     private Action mDebugAction;
     92     private Action mHprofAction;
     93     private Action mTracingAction;
     94 
     95     private ImageDescriptor mTracingStartImage;
     96     private ImageDescriptor mTracingStopImage;
     97 
     98     public class HProfHandler extends BaseFileHandler implements IHprofDumpHandler {
     99         public final static String ACTION_SAVE = "hprof.save"; //$NON-NLS-1$
    100         public final static String ACTION_OPEN = "hprof.open"; //$NON-NLS-1$
    101 
    102         public final static String DOT_HPROF = ".hprof"; //$NON-NLS-1$
    103 
    104         HProfHandler(Shell parentShell) {
    105             super(parentShell);
    106         }
    107 
    108         @Override
    109         protected String getDialogTitle() {
    110             return Messages.DeviceView_HPROF_Error;
    111         }
    112 
    113         public void onEndFailure(final Client client, final String message) {
    114             mParentShell.getDisplay().asyncExec(new Runnable() {
    115                 public void run() {
    116                     try {
    117                         displayErrorFromUiThread(
    118                                 Messages.DeviceView_Unable_Create_HPROF_For_Application,
    119                                 client.getClientData().getClientDescription(),
    120                                 message != null ? message + "\n\n" : ""); //$NON-NLS-1$ //$NON-NLS-2$
    121                     } finally {
    122                         // this will make sure the dump hprof button is
    123                         // re-enabled for the
    124                         // current selection. as the client is finished dumping
    125                         // an hprof file
    126                         doSelectionChanged(mDeviceList.getSelectedClient());
    127                     }
    128                 }
    129             });
    130         }
    131 
    132         public void onSuccess(final String remoteFilePath, final Client client) {
    133             mParentShell.getDisplay().asyncExec(new Runnable() {
    134                 public void run() {
    135                     final IDevice device = client.getDevice();
    136                     try {
    137                         // get the sync service to pull the HPROF file
    138                         final SyncService sync = client.getDevice().getSyncService();
    139                         if (sync != null) {
    140                             // get from the preference what action to take
    141                             IPreferenceStore store = DdmsPlugin.getDefault().getPreferenceStore();
    142                             String value = store.getString(PreferenceInitializer.ATTR_HPROF_ACTION);
    143 
    144                             if (ACTION_OPEN.equals(value)) {
    145                                 File temp = File.createTempFile("android", DOT_HPROF); //$NON-NLS-1$
    146                                 final String tempPath = temp.getAbsolutePath();
    147                                 SyncProgressHelper.run(new SyncRunnable() {
    148 
    149                                     public void run(ISyncProgressMonitor monitor)
    150                                                 throws SyncException, IOException,
    151                                                 TimeoutException {
    152                                         sync.pullFile(remoteFilePath, tempPath, monitor);
    153                                     }
    154 
    155                                     public void close() {
    156                                         sync.close();
    157                                     }
    158                                 },
    159                                         String.format(Messages.DeviceView_Pulling_From_Device,
    160                                                 remoteFilePath),
    161                                         mParentShell);
    162 
    163                                 open(tempPath);
    164                             } else {
    165                                 // default action is ACTION_SAVE
    166                                 promptAndPull(sync,
    167                                         client.getClientData().getClientDescription() + DOT_HPROF,
    168                                         remoteFilePath, Messages.DeviceView_Save_HPROF_File);
    169 
    170                             }
    171                         } else {
    172                             displayErrorFromUiThread(
    173                                     Messages.DeviceView_Unable_Download_HPROF_From_Device_One_Param_First_Message,
    174                                     device.getSerialNumber());
    175                         }
    176                     } catch (SyncException e) {
    177                         if (e.wasCanceled() == false) {
    178                             displayErrorFromUiThread(
    179                                     Messages.DeviceView_Unable_Download_HPROF_From_Device_Two_Param,
    180                                     device.getSerialNumber(), e.getMessage());
    181                         }
    182                     } catch (Exception e) {
    183                         displayErrorFromUiThread(
    184                                 Messages.DeviceView_Unable_Download_HPROF_From_Device_One_Param_Second_Message,
    185                                 device.getSerialNumber());
    186 
    187                     } finally {
    188                         // this will make sure the dump hprof button is
    189                         // re-enabled for the
    190                         // current selection. as the client is finished dumping
    191                         // an hprof file
    192                         doSelectionChanged(mDeviceList.getSelectedClient());
    193                     }
    194                 }
    195             });
    196         }
    197 
    198         public void onSuccess(final byte[] data, final Client client) {
    199             mParentShell.getDisplay().asyncExec(new Runnable() {
    200                 public void run() {
    201                     // get from the preference what action to take
    202                     IPreferenceStore store = DdmsPlugin.getDefault().getPreferenceStore();
    203                     String value = store.getString(PreferenceInitializer.ATTR_HPROF_ACTION);
    204 
    205                     if (ACTION_OPEN.equals(value)) {
    206                         try {
    207                             // no need to give an extension since we're going to
    208                             // convert the
    209                             // file anyway after.
    210                             File tempFile = saveTempFile(data, null /* extension */);
    211                             open(tempFile.getAbsolutePath());
    212                         } catch (Exception e) {
    213                             String errorMsg = e.getMessage();
    214                             displayErrorFromUiThread(
    215                                     Messages.DeviceView_Failed_To_Save_HPROF_Data,
    216                                     errorMsg != null ? ":\n" + errorMsg : "."); //$NON-NLS-1$ //$NON-NLS-2$
    217                         }
    218                     } else {
    219                         // default action is ACTION_SAVE
    220                         promptAndSave(client.getClientData().getClientDescription() + DOT_HPROF,
    221                                 data, Messages.DeviceView_Save_HPROF_File);
    222                     }
    223                 }
    224             });
    225         }
    226 
    227         private void open(String path) throws IOException, InterruptedException, PartInitException {
    228             // make a temp file to convert the hprof into something
    229             // readable by normal tools
    230             File temp = File.createTempFile("android", DOT_HPROF); //$NON-NLS-1$
    231             String tempPath = temp.getAbsolutePath();
    232 
    233             String[] command = new String[3];
    234             command[0] = DdmsPlugin.getHprofConverter();
    235             command[1] = path;
    236             command[2] = tempPath;
    237 
    238             Process p = Runtime.getRuntime().exec(command);
    239             p.waitFor();
    240 
    241             IFileStore fileStore = EFS.getLocalFileSystem().getStore(new Path(tempPath));
    242             if (!fileStore.fetchInfo().isDirectory() && fileStore.fetchInfo().exists()) {
    243                 // before we open the file in an editor window, we make sure the
    244                 // current
    245                 // workbench page has an editor area (typically the ddms
    246                 // perspective doesn't).
    247                 IWorkbench workbench = PlatformUI.getWorkbench();
    248                 IWorkbenchWindow window = workbench.getActiveWorkbenchWindow();
    249                 IWorkbenchPage page = window.getActivePage();
    250                 if (page.isEditorAreaVisible() == false) {
    251                     IAdaptable input;
    252                     if (page != null)
    253                         input = page.getInput();
    254                     else
    255                         input = ResourcesPlugin.getWorkspace().getRoot();
    256                     try {
    257                         workbench.showPerspective("org.eclipse.debug.ui.DebugPerspective", //$NON-NLS-1$
    258                                 window, input);
    259                     } catch (WorkbenchException e) {
    260                     }
    261                 }
    262 
    263                 IDE.openEditorOnFileStore(page, fileStore);
    264             }
    265         }
    266     }
    267 
    268     public DeviceView() {
    269         // the view is declared with allowMultiple="false" so we
    270         // can safely do this.
    271         sThis = this;
    272     }
    273 
    274     public static DeviceView getInstance() {
    275         return sThis;
    276     }
    277 
    278     @Override
    279     public void createPartControl(Composite parent) {
    280         mParentShell = parent.getShell();
    281 
    282         ImageLoader loader = ImageLoader.getDdmUiLibLoader();
    283 
    284         mDeviceList = new DevicePanel(USE_SELECTED_DEBUG_PORT);
    285         mDeviceList.createPanel(parent);
    286         mDeviceList.addSelectionListener(this);
    287 
    288         DdmsPlugin plugin = DdmsPlugin.getDefault();
    289         mDeviceList.addSelectionListener(plugin);
    290         plugin.setListeningState(true);
    291 
    292         mCaptureAction = new Action(Messages.DeviceView_Screen_Capture) {
    293             @Override
    294             public void run() {
    295                 ScreenShotDialog dlg = new ScreenShotDialog(
    296                         DdmsPlugin.getDisplay().getActiveShell());
    297                 dlg.open(mDeviceList.getSelectedDevice());
    298             }
    299         };
    300         mCaptureAction.setToolTipText(Messages.DeviceView_Screen_Capture_Tooltip);
    301         mCaptureAction.setImageDescriptor(loader.loadDescriptor("capture.png")); //$NON-NLS-1$
    302 
    303         mResetAdbAction = new Action(Messages.DeviceView_Reset_ADB) {
    304             @Override
    305             public void run() {
    306                 AndroidDebugBridge bridge = AndroidDebugBridge.getBridge();
    307                 if (bridge != null) {
    308                     if (bridge.restart() == false) {
    309                         // get the current Display
    310                         final Display display = DdmsPlugin.getDisplay();
    311 
    312                         // dialog box only run in ui thread..
    313                         display.asyncExec(new Runnable() {
    314                             public void run() {
    315                                 Shell shell = display.getActiveShell();
    316                                 MessageDialog.openError(shell, Messages.DeviceView_ADB_Error,
    317                                         Messages.DeviceView_ADB_Failed_Restart);
    318                             }
    319                         });
    320                     }
    321                 }
    322             }
    323         };
    324         mResetAdbAction.setToolTipText(Messages.DeviceView_Reset_ADB_Host_Deamon);
    325         mResetAdbAction.setImageDescriptor(PlatformUI.getWorkbench()
    326                 .getSharedImages().getImageDescriptor(
    327                         ISharedImages.IMG_OBJS_WARN_TSK));
    328 
    329         mKillAppAction = new Action() {
    330             @Override
    331             public void run() {
    332                 mDeviceList.killSelectedClient();
    333             }
    334         };
    335 
    336         mKillAppAction.setText(Messages.DeviceView_Stop_Process);
    337         mKillAppAction.setToolTipText(Messages.DeviceView_Stop_Process_Tooltip);
    338         mKillAppAction.setImageDescriptor(loader.loadDescriptor(DevicePanel.ICON_HALT));
    339 
    340         mGcAction = new Action() {
    341             @Override
    342             public void run() {
    343                 mDeviceList.forceGcOnSelectedClient();
    344             }
    345         };
    346 
    347         mGcAction.setText(Messages.DeviceView_Cause_GC);
    348         mGcAction.setToolTipText(Messages.DeviceView_Cause_GC_Tooltip);
    349         mGcAction.setImageDescriptor(loader.loadDescriptor(DevicePanel.ICON_GC));
    350 
    351         mHprofAction = new Action() {
    352             @Override
    353             public void run() {
    354                 mDeviceList.dumpHprof();
    355                 doSelectionChanged(mDeviceList.getSelectedClient());
    356             }
    357         };
    358         mHprofAction.setText(Messages.DeviceView_Dump_HPROF_File);
    359         mHprofAction.setToolTipText(Messages.DeviceView_Dump_HPROF_File_Tooltip);
    360         mHprofAction.setImageDescriptor(loader.loadDescriptor(DevicePanel.ICON_HPROF));
    361 
    362         mUpdateHeapAction = new Action(Messages.DeviceView_Update_Heap, IAction.AS_CHECK_BOX) {
    363             @Override
    364             public void run() {
    365                 boolean enable = mUpdateHeapAction.isChecked();
    366                 mDeviceList.setEnabledHeapOnSelectedClient(enable);
    367             }
    368         };
    369         mUpdateHeapAction.setToolTipText(Messages.DeviceView_Update_Heap_Tooltip);
    370         mUpdateHeapAction.setImageDescriptor(loader.loadDescriptor(DevicePanel.ICON_HEAP));
    371 
    372         mUpdateThreadAction = new Action(Messages.DeviceView_Threads, IAction.AS_CHECK_BOX) {
    373             @Override
    374             public void run() {
    375                 boolean enable = mUpdateThreadAction.isChecked();
    376                 mDeviceList.setEnabledThreadOnSelectedClient(enable);
    377             }
    378         };
    379         mUpdateThreadAction.setToolTipText(Messages.DeviceView_Threads_Tooltip);
    380         mUpdateThreadAction.setImageDescriptor(loader.loadDescriptor(DevicePanel.ICON_THREAD));
    381 
    382         mTracingAction = new Action() {
    383             @Override
    384             public void run() {
    385                 mDeviceList.toggleMethodProfiling();
    386             }
    387         };
    388         mTracingAction.setText(Messages.DeviceView_Start_Method_Profiling);
    389         mTracingAction.setToolTipText(Messages.DeviceView_Start_Method_Profiling_Tooltip);
    390         mTracingStartImage = loader.loadDescriptor(DevicePanel.ICON_TRACING_START);
    391         mTracingStopImage = loader.loadDescriptor(DevicePanel.ICON_TRACING_STOP);
    392         mTracingAction.setImageDescriptor(mTracingStartImage);
    393 
    394         mDebugAction = new Action(Messages.DeviceView_Debug_Process) {
    395             @Override
    396             public void run() {
    397                 if (DdmsPlugin.getDefault().hasDebuggerConnectors()) {
    398                     Client currentClient = mDeviceList.getSelectedClient();
    399                     if (currentClient != null) {
    400                         ClientData clientData = currentClient.getClientData();
    401 
    402                         // make sure the client can be debugged
    403                         switch (clientData.getDebuggerConnectionStatus()) {
    404                             case ERROR: {
    405                                 Display display = DdmsPlugin.getDisplay();
    406                                 Shell shell = display.getActiveShell();
    407                                 MessageDialog.openError(shell,
    408                                         Messages.DeviceView_Debug_Process_Title,
    409                                         Messages.DeviceView_Process_Debug_Already_In_Use);
    410                                 return;
    411                             }
    412                             case ATTACHED: {
    413                                 Display display = DdmsPlugin.getDisplay();
    414                                 Shell shell = display.getActiveShell();
    415                                 MessageDialog.openError(shell,
    416                                         Messages.DeviceView_Debug_Process_Title,
    417                                         Messages.DeviceView_Process_Already_Being_Debugged);
    418                                 return;
    419                             }
    420                         }
    421 
    422                         // get the name of the client
    423                         String packageName = clientData.getClientDescription();
    424                         if (packageName != null) {
    425 
    426                             // try all connectors till one returns true.
    427                             IDebuggerConnector[] connectors =
    428                                     DdmsPlugin.getDefault().getDebuggerConnectors();
    429 
    430                             if (connectors != null) {
    431                                 for (IDebuggerConnector connector : connectors) {
    432                                     try {
    433                                         if (connector.connectDebugger(packageName,
    434                                                 currentClient.getDebuggerListenPort(),
    435                                                 DdmPreferences.getSelectedDebugPort())) {
    436                                             return;
    437                                         }
    438                                     } catch (Throwable t) {
    439                                         // ignore, we'll just not use this
    440                                         // implementation
    441                                     }
    442                                 }
    443                             }
    444 
    445                             // if we get to this point, then we failed to find a
    446                             // project
    447                             // that matched the application to debug
    448                             Display display = DdmsPlugin.getDisplay();
    449                             Shell shell = display.getActiveShell();
    450                             MessageDialog.openError(shell, Messages.DeviceView_Debug_Process_Title,
    451                                     String.format(
    452                                             Messages.DeviceView_Debug_Session_Failed,
    453                                             packageName));
    454                         }
    455                     }
    456                 }
    457             }
    458         };
    459         mDebugAction.setToolTipText(Messages.DeviceView_Debug_Process_Tooltip);
    460         mDebugAction.setImageDescriptor(loader.loadDescriptor("debug-attach.png")); //$NON-NLS-1$
    461         mDebugAction.setEnabled(DdmsPlugin.getDefault().hasDebuggerConnectors());
    462 
    463         placeActions();
    464 
    465         ClientData.setHprofDumpHandler(new HProfHandler(mParentShell));
    466         AndroidDebugBridge.addClientChangeListener(this);
    467         ClientData.setMethodProfilingHandler(new MethodProfilingHandler(mParentShell) {
    468             @Override
    469             protected void open(String tempPath) {
    470                 if (DdmsPlugin.getDefault().launchTraceview(tempPath) == false) {
    471                     super.open(tempPath);
    472                 }
    473             }
    474         });
    475     }
    476 
    477     @Override
    478     public void setFocus() {
    479         mDeviceList.setFocus();
    480     }
    481 
    482     /**
    483      * Sent when a new {@link IDevice} and {@link Client} are selected.
    484      *
    485      * @param selectedDevice the selected device. If null, no devices are
    486      *            selected.
    487      * @param selectedClient The selected client. If null, no clients are
    488      *            selected.
    489      */
    490     public void selectionChanged(IDevice selectedDevice, Client selectedClient) {
    491         // update the buttons
    492         doSelectionChanged(selectedClient);
    493         doSelectionChanged(selectedDevice);
    494     }
    495 
    496     private void doSelectionChanged(Client selectedClient) {
    497         // update the buttons
    498         if (selectedClient != null) {
    499             if (USE_SELECTED_DEBUG_PORT) {
    500                 // set the client as the debug client
    501                 selectedClient.setAsSelectedClient();
    502             }
    503 
    504             mDebugAction.setEnabled(DdmsPlugin.getDefault().hasDebuggerConnectors());
    505             mKillAppAction.setEnabled(true);
    506             mGcAction.setEnabled(true);
    507 
    508             mUpdateHeapAction.setEnabled(true);
    509             mUpdateHeapAction.setChecked(selectedClient.isHeapUpdateEnabled());
    510 
    511             mUpdateThreadAction.setEnabled(true);
    512             mUpdateThreadAction.setChecked(selectedClient.isThreadUpdateEnabled());
    513 
    514             ClientData data = selectedClient.getClientData();
    515 
    516             if (data.hasFeature(ClientData.FEATURE_HPROF)) {
    517                 mHprofAction.setEnabled(data.hasPendingHprofDump() == false);
    518                 mHprofAction.setToolTipText(Messages.DeviceView_Dump_HPROF_File);
    519             } else {
    520                 mHprofAction.setEnabled(false);
    521                 mHprofAction
    522                         .setToolTipText(Messages.DeviceView_Dump_HPROF_File_Not_Supported_By_VM);
    523             }
    524 
    525             if (data.hasFeature(ClientData.FEATURE_PROFILING)) {
    526                 mTracingAction.setEnabled(true);
    527                 if (data.getMethodProfilingStatus() == MethodProfilingStatus.ON) {
    528                     mTracingAction
    529                             .setToolTipText(Messages.DeviceView_Stop_Method_Profiling_Tooltip);
    530                     mTracingAction.setText(Messages.DeviceView_Stop_Method_Profiling);
    531                     mTracingAction.setImageDescriptor(mTracingStopImage);
    532                 } else {
    533                     mTracingAction
    534                             .setToolTipText(Messages.DeviceView_Start_Method_Profiling_Tooltip);
    535                     mTracingAction.setImageDescriptor(mTracingStartImage);
    536                     mTracingAction.setText(Messages.DeviceView_Start_Method_Profiling);
    537                 }
    538             } else {
    539                 mTracingAction.setEnabled(false);
    540                 mTracingAction.setImageDescriptor(mTracingStartImage);
    541                 mTracingAction
    542                         .setToolTipText(Messages.DeviceView_Start_Method_Profiling_Not_Suported_By_Vm);
    543                 mTracingAction.setText(Messages.DeviceView_Start_Method_Profiling);
    544             }
    545         } else {
    546             if (USE_SELECTED_DEBUG_PORT) {
    547                 // set the client as the debug client
    548                 AndroidDebugBridge bridge = AndroidDebugBridge.getBridge();
    549                 if (bridge != null) {
    550                     bridge.setSelectedClient(null);
    551                 }
    552             }
    553 
    554             mDebugAction.setEnabled(false);
    555             mKillAppAction.setEnabled(false);
    556             mGcAction.setEnabled(false);
    557             mUpdateHeapAction.setChecked(false);
    558             mUpdateHeapAction.setEnabled(false);
    559             mUpdateThreadAction.setEnabled(false);
    560             mUpdateThreadAction.setChecked(false);
    561             mHprofAction.setEnabled(false);
    562 
    563             mHprofAction.setEnabled(false);
    564             mHprofAction.setToolTipText(Messages.DeviceView_Dump_HPROF_File);
    565 
    566             mTracingAction.setEnabled(false);
    567             mTracingAction.setImageDescriptor(mTracingStartImage);
    568             mTracingAction.setToolTipText(Messages.DeviceView_Start_Method_Profiling_Tooltip);
    569             mTracingAction.setText(Messages.DeviceView_Start_Method_Profiling);
    570         }
    571     }
    572 
    573     private void doSelectionChanged(IDevice selectedDevice) {
    574         mCaptureAction.setEnabled(selectedDevice != null);
    575     }
    576 
    577     /**
    578      * Place the actions in the ui.
    579      */
    580     private final void placeActions() {
    581         IActionBars actionBars = getViewSite().getActionBars();
    582 
    583         // first in the menu
    584         IMenuManager menuManager = actionBars.getMenuManager();
    585         menuManager.removeAll();
    586         menuManager.add(mDebugAction);
    587         menuManager.add(new Separator());
    588         menuManager.add(mUpdateHeapAction);
    589         menuManager.add(mHprofAction);
    590         menuManager.add(mGcAction);
    591         menuManager.add(new Separator());
    592         menuManager.add(mUpdateThreadAction);
    593         menuManager.add(mTracingAction);
    594         menuManager.add(new Separator());
    595         menuManager.add(mKillAppAction);
    596         menuManager.add(new Separator());
    597         menuManager.add(mCaptureAction);
    598         menuManager.add(new Separator());
    599         menuManager.add(mResetAdbAction);
    600 
    601         // and then in the toolbar
    602         IToolBarManager toolBarManager = actionBars.getToolBarManager();
    603         toolBarManager.removeAll();
    604         toolBarManager.add(mDebugAction);
    605         toolBarManager.add(new Separator());
    606         toolBarManager.add(mUpdateHeapAction);
    607         toolBarManager.add(mHprofAction);
    608         toolBarManager.add(mGcAction);
    609         toolBarManager.add(new Separator());
    610         toolBarManager.add(mUpdateThreadAction);
    611         toolBarManager.add(mTracingAction);
    612         toolBarManager.add(new Separator());
    613         toolBarManager.add(mKillAppAction);
    614         toolBarManager.add(new Separator());
    615         toolBarManager.add(mCaptureAction);
    616     }
    617 
    618     public void clientChanged(final Client client, int changeMask) {
    619         if ((changeMask & Client.CHANGE_METHOD_PROFILING_STATUS) == Client.CHANGE_METHOD_PROFILING_STATUS) {
    620             if (mDeviceList.getSelectedClient() == client) {
    621                 mParentShell.getDisplay().asyncExec(new Runnable() {
    622                     public void run() {
    623                         // force refresh of the button enabled state.
    624                         doSelectionChanged(client);
    625                     }
    626                 });
    627             }
    628         }
    629     }
    630 }
    631