diff options
author | Xavier Ducrohet <xav@android.com> | 2010-01-28 10:44:02 -0800 |
---|---|---|
committer | Xavier Ducrohet <xav@android.com> | 2010-01-28 13:47:12 -0800 |
commit | de0716ae5b7caf7766e656b93bff971ce75d94b6 (patch) | |
tree | a8fde8bad38c40805f5390d6ef7f99611736f0ad /ddms | |
parent | 2d653fac401f9b707dbe4c17eb1045143401ffb0 (diff) | |
download | sdk-de0716ae5b7caf7766e656b93bff971ce75d94b6.zip sdk-de0716ae5b7caf7766e656b93bff971ce75d94b6.tar.gz sdk-de0716ae5b7caf7766e656b93bff971ce75d94b6.tar.bz2 |
DDMS: Add support for profiling with VM able to send the result through JDWP.
Older VMs need to write the trace file on the SD Card which requires
the appropriate permission. This new mode directly streams the trace
file from the VM to DDMS.
Bug: 2160407
Change-Id: Ic0e0813d8453761caecb990d85ca7e3baf1d237a
Diffstat (limited to 'ddms')
5 files changed, 114 insertions, 16 deletions
diff --git a/ddms/libs/ddmlib/src/com/android/ddmlib/Client.java b/ddms/libs/ddmlib/src/com/android/ddmlib/Client.java index 52c9506..efa47d7 100644 --- a/ddms/libs/ddmlib/src/com/android/ddmlib/Client.java +++ b/ddms/libs/ddmlib/src/com/android/ddmlib/Client.java @@ -241,7 +241,7 @@ public class Client { } public void toggleMethodProfiling() { - boolean canStream = false; //mClientData.hasFeature(ClientData.FEATURE_PROFILING_STREAMING); + boolean canStream = mClientData.hasFeature(ClientData.FEATURE_PROFILING_STREAMING); try { if (mClientData.getMethodProfilingStatus() == MethodProfilingStatus.ON) { if (canStream) { diff --git a/ddms/libs/ddmlib/src/com/android/ddmlib/ClientData.java b/ddms/libs/ddmlib/src/com/android/ddmlib/ClientData.java index 53e1352..a064634 100644 --- a/ddms/libs/ddmlib/src/com/android/ddmlib/ClientData.java +++ b/ddms/libs/ddmlib/src/com/android/ddmlib/ClientData.java @@ -18,6 +18,7 @@ package com.android.ddmlib; import com.android.ddmlib.HeapSegment.HeapSegmentElement; +import java.io.File; import java.nio.BufferUnderflowException; import java.nio.ByteBuffer; import java.util.ArrayList; @@ -315,10 +316,29 @@ public class ClientData { void onSuccess(String remoteFilePath, Client client); /** - * Called when method tracing failed. + * Called when a method tracing was successful. + * @param remoteFilePath the device-side path of the trace file. * @param client the client that was profiled. */ - void onFailure(Client client); + void onSuccess(File localFile, Client client); + + /** + * Called when method tracing failed to start + * @param client the client that was profiled. + */ + void onStartFailure(Client client); + + /** + * Called when method tracing failed to end on the VM side + * @param client the client that was profiled. + */ + void onEndFailure(Client client); + + /** + * Called when method tracing failed to end locally. + * @param client the client that was profiled. + */ + void onEndLocalFailure(Client client, String message); } /** diff --git a/ddms/libs/ddmlib/src/com/android/ddmlib/HandleProfiling.java b/ddms/libs/ddmlib/src/com/android/ddmlib/HandleProfiling.java index fcc1d26..7d2eb45 100644 --- a/ddms/libs/ddmlib/src/com/android/ddmlib/HandleProfiling.java +++ b/ddms/libs/ddmlib/src/com/android/ddmlib/HandleProfiling.java @@ -19,6 +19,8 @@ package com.android.ddmlib; import com.android.ddmlib.ClientData.IMethodProfilingHandler; import com.android.ddmlib.ClientData.MethodProfilingStatus; +import java.io.File; +import java.io.FileOutputStream; import java.io.IOException; import java.nio.ByteBuffer; @@ -154,7 +156,7 @@ final class HandleProfiling extends ChunkHandler { Log.d("ddm-prof", "Method profiling has finished"); } else { - handler.onFailure(client); + handler.onEndFailure(client); Log.w("ddm-prof", "Method profiling has failed (check device log)"); } @@ -213,12 +215,42 @@ final class HandleProfiling extends ChunkHandler { * complete .trace file. */ private void handleMPSE(Client client, ByteBuffer data) { - // TODO - byte[] stuff = new byte[Math.min(100, data.capacity())]; - data.get(stuff, 0, stuff.length); - String sample = new String(stuff); - Log.e("ddm-prof", "GOT MPSE (" + data.capacity() + " bytes): '" + - sample + "' ..."); + IMethodProfilingHandler handler = ClientData.getMethodProfilingHandler(); + if (handler != null) { + FileOutputStream fos = null; + try { + File f = File.createTempFile(client.getClientData().getClientDescription(), + ".trace"); + fos = new FileOutputStream(f); + + byte[] stuff = new byte[data.capacity()]; + data.get(stuff, 0, stuff.length); + + fos.write(stuff); + fos.close(); + fos = null; + + Log.d("ddm-prof", "got trace file, size: " + data.capacity() + " bytes"); + + handler.onSuccess(f, client); + } catch (IOException e) { + handler.onEndLocalFailure(client, e.getMessage()); + + Log.e("ddm-prof", "fail to write trace file: " + e.getMessage()); + Log.e("ddm-prof", e); + } finally { + if (fos != null) { + try { + fos.close(); + } catch (IOException e) { + //ignore + } + } + } + } + + client.getClientData().setMethodProfilingStatus(MethodProfilingStatus.OFF); + client.update(Client.CHANGE_METHOD_PROFILING_STATUS); } /** @@ -255,7 +287,9 @@ final class HandleProfiling extends ChunkHandler { } private void handleFAIL(Client client, ByteBuffer data) { - // this can be sent if MPRS failed (like wrong permission) + // this can be sent if + // - MPRS failed (like wrong permission) + // - MPSE failed for whatever reason String filename = client.getClientData().getPendingMethodProfiling(); if (filename != null) { @@ -265,9 +299,15 @@ final class HandleProfiling extends ChunkHandler { // and notify of failure IMethodProfilingHandler handler = ClientData.getMethodProfilingHandler(); if (handler != null) { - handler.onFailure(client); + handler.onStartFailure(client); + } + } else { + // this is MPRE + // notify of failure + IMethodProfilingHandler handler = ClientData.getMethodProfilingHandler(); + if (handler != null) { + handler.onEndFailure(client); } - } // send a query to know the current status diff --git a/ddms/libs/ddmuilib/src/com/android/ddmuilib/InfoPanel.java b/ddms/libs/ddmuilib/src/com/android/ddmuilib/InfoPanel.java index 6cbb999..d6979cb 100644 --- a/ddms/libs/ddmuilib/src/com/android/ddmuilib/InfoPanel.java +++ b/ddms/libs/ddmuilib/src/com/android/ddmuilib/InfoPanel.java @@ -164,10 +164,22 @@ public class InfoPanel extends TablePanel { item.setText(1, isDdmAware); item = mTable.getItem(ENT_PROCESS_ID); item.setText(1, pid); + item = mTable.getItem(ENT_SUPPORTS_PROFILING); - item.setText(1, Boolean.toString(cd.hasFeature(ClientData.FEATURE_PROFILING))); + if (cd.hasFeature(ClientData.FEATURE_PROFILING_STREAMING)) { + item.setText(1, "Yes"); + } else if (cd.hasFeature(ClientData.FEATURE_PROFILING)) { + item.setText(1, "Yes (Application must be able to write on the SD Card)"); + } else { + item.setText(1, "No"); + } + item = mTable.getItem(ENT_SUPPORTS_HPROF); - item.setText(1, Boolean.toString(cd.hasFeature(ClientData.FEATURE_HPROF))); + if (cd.hasFeature(ClientData.FEATURE_HPROF)) { + item.setText(1, "Yes (Application must be able to write on the SD Card)"); + } else { + item.setText(1, "No"); + } } mCol2.pack(); diff --git a/ddms/libs/ddmuilib/src/com/android/ddmuilib/handler/MethodProfilingHandler.java b/ddms/libs/ddmuilib/src/com/android/ddmuilib/handler/MethodProfilingHandler.java index f469a7d..c029186 100644 --- a/ddms/libs/ddmuilib/src/com/android/ddmuilib/handler/MethodProfilingHandler.java +++ b/ddms/libs/ddmuilib/src/com/android/ddmuilib/handler/MethodProfilingHandler.java @@ -45,7 +45,7 @@ public class MethodProfilingHandler extends BaseFileHandler super(parentShell); } - public void onFailure(final Client client) { + public void onStartFailure(final Client client) { mParentShell.getDisplay().asyncExec(new Runnable() { public void run() { displayError( @@ -56,6 +56,28 @@ public class MethodProfilingHandler extends BaseFileHandler }); } + public void onEndFailure(final Client client) { + mParentShell.getDisplay().asyncExec(new Runnable() { + public void run() { + displayError( + "Unable to finish Method Profiling for application '%1$s'.\n" + + "Check logcat for more information.", + client.getClientData().getClientDescription()); + } + }); + } + + public void onEndLocalFailure(final Client client, final String message) { + mParentShell.getDisplay().asyncExec(new Runnable() { + public void run() { + displayError(String.format( + "Unable to write trace file locally for application\n\t%1$s\n\n%2$s", + client.getClientData().getClientDescription(), + message)); + } + }); + } + public void onSuccess(final String remoteFilePath, final Client client) { mParentShell.getDisplay().asyncExec(new Runnable() { public void run() { @@ -85,6 +107,10 @@ public class MethodProfilingHandler extends BaseFileHandler }); } + public void onSuccess(File localFile, final Client client) { + openInTraceview(localFile.getAbsolutePath()); + } + private void pullAndOpen(SyncService sync, String remoteFilePath) throws InvocationTargetException, InterruptedException, IOException { // get a temp file |