• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
HProfHandler(Shell parentShell)104         HProfHandler(Shell parentShell) {
105             super(parentShell);
106         }
107 
108         @Override
getDialogTitle()109         protected String getDialogTitle() {
110             return Messages.DeviceView_HPROF_Error;
111         }
112 
onEndFailure(final Client client, final String message)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 
onSuccess(final String remoteFilePath, final Client client)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 
onSuccess(final byte[] data, final Client client)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 
open(String path)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 
DeviceView()268     public DeviceView() {
269         // the view is declared with allowMultiple="false" so we
270         // can safely do this.
271         sThis = this;
272     }
273 
getInstance()274     public static DeviceView getInstance() {
275         return sThis;
276     }
277 
278     @Override
createPartControl(Composite parent)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
setFocus()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      */
selectionChanged(IDevice selectedDevice, Client selectedClient)490     public void selectionChanged(IDevice selectedDevice, Client selectedClient) {
491         // update the buttons
492         doSelectionChanged(selectedClient);
493         doSelectionChanged(selectedDevice);
494     }
495 
doSelectionChanged(Client selectedClient)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 
doSelectionChanged(IDevice selectedDevice)573     private void doSelectionChanged(IDevice selectedDevice) {
574         mCaptureAction.setEnabled(selectedDevice != null);
575     }
576 
577     /**
578      * Place the actions in the ui.
579      */
placeActions()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 
clientChanged(final Client client, int changeMask)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