• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2009 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.ddmuilib.handler;
18 
19 import com.android.ddmlib.Client;
20 import com.android.ddmlib.ClientData.IMethodProfilingHandler;
21 import com.android.ddmlib.DdmConstants;
22 import com.android.ddmlib.IDevice;
23 import com.android.ddmlib.Log;
24 import com.android.ddmlib.SyncException;
25 import com.android.ddmlib.SyncService;
26 import com.android.ddmlib.SyncService.ISyncProgressMonitor;
27 import com.android.ddmlib.TimeoutException;
28 import com.android.ddmuilib.DdmUiPreferences;
29 import com.android.ddmuilib.SyncProgressHelper;
30 import com.android.ddmuilib.SyncProgressHelper.SyncRunnable;
31 import com.android.ddmuilib.console.DdmConsole;
32 
33 import org.eclipse.swt.widgets.Shell;
34 
35 import java.io.BufferedReader;
36 import java.io.File;
37 import java.io.IOException;
38 import java.io.InputStreamReader;
39 import java.lang.reflect.InvocationTargetException;
40 
41 /**
42  * Handler for Method tracing.
43  * This will pull the trace file into a temp file and launch traceview.
44  */
45 public class MethodProfilingHandler extends BaseFileHandler
46         implements IMethodProfilingHandler {
47 
MethodProfilingHandler(Shell parentShell)48     public MethodProfilingHandler(Shell parentShell) {
49         super(parentShell);
50     }
51 
52     @Override
getDialogTitle()53     protected String getDialogTitle() {
54         return "Method Profiling Error";
55     }
56 
onStartFailure(final Client client, final String message)57     public void onStartFailure(final Client client, final String message) {
58         displayErrorInUiThread(
59                 "Unable to create Method Profiling file for application '%1$s'\n\n%2$s" +
60                 "Check logcat for more information.",
61                 client.getClientData().getClientDescription(),
62                 message != null ? message + "\n\n" : "");
63     }
64 
onEndFailure(final Client client, final String message)65     public void onEndFailure(final Client client, final String message) {
66         displayErrorInUiThread(
67                 "Unable to finish Method Profiling for application '%1$s'\n\n%2$s" +
68                 "Check logcat for more information.",
69                 client.getClientData().getClientDescription(),
70                 message != null ? message + "\n\n" : "");
71     }
72 
onSuccess(final String remoteFilePath, final Client client)73     public void onSuccess(final String remoteFilePath, final Client client) {
74         mParentShell.getDisplay().asyncExec(new Runnable() {
75             public void run() {
76                 if (remoteFilePath == null) {
77                     displayErrorFromUiThread(
78                             "Unable to download trace file: unknown file name.\n" +
79                             "This can happen if you disconnected the device while recording the trace.");
80                     return;
81                 }
82 
83                 final IDevice device = client.getDevice();
84                 try {
85                     // get the sync service to pull the HPROF file
86                     final SyncService sync = client.getDevice().getSyncService();
87                     if (sync != null) {
88                         pullAndOpen(sync, remoteFilePath);
89                     } else {
90                         displayErrorFromUiThread(
91                                 "Unable to download trace file from device '%1$s'.",
92                                 device.getSerialNumber());
93                     }
94                 } catch (Exception e) {
95                     displayErrorFromUiThread("Unable to download trace file from device '%1$s'.",
96                             device.getSerialNumber());
97                 }
98             }
99 
100         });
101     }
102 
onSuccess(byte[] data, final Client client)103     public void onSuccess(byte[] data, final Client client) {
104         try {
105             File tempFile = saveTempFile(data, DdmConstants.DOT_TRACE);
106             open(tempFile.getAbsolutePath());
107         } catch (IOException e) {
108             String errorMsg = e.getMessage();
109             displayErrorInUiThread(
110                     "Failed to save trace data into temp file%1$s",
111                     errorMsg != null ? ":\n" + errorMsg : ".");
112         }
113     }
114 
115     /**
116      * pulls and open a file. This is run from the UI thread.
117      */
pullAndOpen(final SyncService sync, final String remoteFilePath)118     private void pullAndOpen(final SyncService sync, final String remoteFilePath)
119             throws InvocationTargetException, InterruptedException, IOException {
120         // get a temp file
121         File temp = File.createTempFile("android", DdmConstants.DOT_TRACE); //$NON-NLS-1$
122         final String tempPath = temp.getAbsolutePath();
123 
124         // pull the file
125         try {
126             SyncProgressHelper.run(new SyncRunnable() {
127                     public void run(ISyncProgressMonitor monitor)
128                             throws SyncException, IOException, TimeoutException {
129                         sync.pullFile(remoteFilePath, tempPath, monitor);
130                     }
131 
132                     public void close() {
133                         sync.close();
134                     }
135                 },
136                 String.format("Pulling %1$s from the device", remoteFilePath), mParentShell);
137 
138             // open the temp file in traceview
139             open(tempPath);
140         } catch (SyncException e) {
141             if (e.wasCanceled() == false) {
142                 displayErrorFromUiThread("Unable to download trace file:\n\n%1$s", e.getMessage());
143             }
144         } catch (TimeoutException e) {
145             displayErrorFromUiThread("Unable to download trace file:\n\ntimeout");
146         }
147     }
148 
open(String tempPath)149     protected void open(String tempPath) {
150         // now that we have the file, we need to launch traceview
151         String[] command = new String[2];
152         command[0] = DdmUiPreferences.getTraceview();
153         command[1] = tempPath;
154 
155         try {
156             final Process p = Runtime.getRuntime().exec(command);
157 
158             // create a thread for the output
159             new Thread("Traceview output") {
160                 @Override
161                 public void run() {
162                     // create a buffer to read the stderr output
163                     InputStreamReader is = new InputStreamReader(p.getErrorStream());
164                     BufferedReader resultReader = new BufferedReader(is);
165 
166                     // read the lines as they come. if null is returned, it's
167                     // because the process finished
168                     try {
169                         while (true) {
170                             String line = resultReader.readLine();
171                             if (line != null) {
172                                 DdmConsole.printErrorToConsole("Traceview: " + line);
173                             } else {
174                                 break;
175                             }
176                         }
177                         // get the return code from the process
178                         p.waitFor();
179                     } catch (Exception e) {
180                         Log.e("traceview", e);
181                     }
182                 }
183             }.start();
184         } catch (IOException e) {
185             Log.e("traceview", e);
186         }
187     }
188 }
189