Development Tools‎ > ‎Eclipse SDK‎ > ‎

Augmenting DDMS

This tutorial describes how I went about adding a feature to the DDMS Eclipse plugin.  I had never written an Eclipse plugin before and the majority of my Java experience has been with Android apps, so this guide is written for noobs in that respect.  Being unfamiliar with the dependency system in Eclipse, I spent a few hours wandering in the dark; hopefully this guide will expedite the process for future hackers.

This guide assumes some Linux CLI competence.

Motivation

When developing Android applications, one spends a lot of time debugging with DDMS.  Android does integrate with Eclipse's Debug Perspective that allows you to "step" through your code, but often this method must be supplemented by DDMS.  DDMS has a pane called "LogCat" that lets you inspect log statements embedded in the application code a la printf() debugging.  If your app throws an exception,  the stack trace is usually dumped to LogCat, which the developer can inspect to pinpoint the error in their source code.

Currently it's a multi-step process move from LogCat to code.  Given a stack trace like:
java.net.UnknownHostException: Host is unresolved: api.flickr.com:80
    at java.net.Socket.connect(Socket.java:1002)
    [...]
    at com.kostmo.flickr.bettr.CheckUpdateService$CheckForUpdatesTask.doInBackground(CheckUpdateService.java:207)
    at com.kostmo.flickr.bettr.CheckUpdateService$CheckForUpdatesTask.doInBackground(CheckUpdateService.java:1)
    at android.os.AsyncTask$2.call(AsyncTask.java:185)

I might want to inspect the file CheckUpdateService.java at line 207, since it is a member of my package "com.kostmo.flickr.bettr".  So in Eclipse, I would click on the JAVA perspective button, navigate to the file CheckUpdateService.java in the Package Explorer and open it, and finally use CTRL+L to go to line 207.  Complicating things, however, is the fact that sometimes these error message lines are too wide to fit on the screen, obscuring the line number and possibly the filename.  I've been dealing with this by copying the LogCat line and pasting it into a text editor so I can read the whole thing.

In a significant debugging session this adds up to a whole lot of tedious GUI manipulation.  DDMS is a great tool, but could certainly be better.  I started off by filing Issue 5280, but then decided I may be able to get it done myself.

Project Setup

NOTE: This is not the right way.  According to official docs, you should get the *whole tree*, not just the development branch, and "make" it first.  Please ignore this section.

First I had to determine which files I would need to edit.  GitWeb has a long list of Git repositories, some accompanied by descriptions.  After some exploring of the tree, I found the LogCat view in the Eclipse plugin and the LogPanel in the libraries that are also used in the standalone DDMS tool.  The repository applicable to my patch is the development project.

To get the source, I first set up repo according to these instructions.  I created "aosp" as my working directory; paths henceforth in this guide will be relative to this directory.  Note: To add repo to the path of the current user, create/append the following two lines to ~/.bash_profile:
PATH=$PATH:$HOME/bin
export PATH
This will take effect on the next login; run
source ~/.bash_profile
to effect the change immediately.

Then I obtained the source code of the project (also appearing in this list) that I was interested in:
repo sync development

I started a branch called "ddms_goto_error" for my changes to the project:
repo start ddms_goto_error development

Later I found I would also have to fetch some .jar dependencies with:
repo sync prebuilt

At this point I could open the relevant projects in Eclipse.

Resolving Dependencies

I opened the Eclipse plugin project via File -> Import -> Existing Projects into Workspace with the root directory development/tools/eclipse/plugins/com.android.ide.eclipse.ddms.

The ddms-plugin project depends on:
  • ddms
  • ddmlib
  • ddmuilib
Importing with the root directory development/tools/ddms opened all three as projects.
I then had four projects open in eclipse, all with errors.

Project -> Properties -> Java Build Path -> Libraries showed three missing .jar's:
  • jcommon-1.0.12.jar
  • jfreechart-1.0.9-swt.jar
  • jfreechart-1.0.9.jar
These can be found in prebuilt/common/eclipse directory.  I created soft links in the ddms-plugin/libs (development/tools/eclipse/plugins/com.android.ide.eclipse.ddms/libs) directory to these .jar's.

ln -s ../../../../../../prebuilt/common/jfreechart/<some_file>.jar
Refresh the libs folder in Eclipse with F5.

As per these instructions I added prebuilt/linux-x86_64/swt/swt.jar to a new User Library called ANDROID_SWT.  The projects expect this library to exist.

Two additional projects are required to be in the build path of the ddms project:
  • SdkStatsService
  • AndroidPrefs
Import the projects development/tools/sdkstats and development/tools/androidprefs.  To satisfy missing dependencies in SdkStatsService, I created a User Library called ANDROID_ECLIPSE, added the three .jar's from prebuilt/common/eclipse to it, and added the library to the Java Build Path.  This library should also be added to the ddms and ddmuilib projects.

ddmuilib also expects a library called ANDROID_JFREECHART; create yet another user library with this name containing the three .jar's from prebuilt/common/jfreechart.

At this point, errors remained in the META-INF/MANIFEST.MF file of the ddms-plugin project.  I resolved this by clicking "Link Source..." under the Source tab of the Java Build Path, and adding links to the src/ folders of ddmlib and ddmuilib.  I gave these links a "Folder name" of ddmlib-src and ddmuilib-src, respectively.

Now there should be six projects in the workspace with no errors.

Modifying and Testing the Eclipse plugin

I won't dwell much on the code; in outline I created a public routine in LogPanel.java to export the "Message" portion of the error line, then regexp-parsed the line in LogCatView.java, searched for the extracted class in the workspace, and opened the file at the appropriate line.

The search functionality required that I add org.eclipse.jdt.core under "Required Plug-ins" in the Dependencies tab in the file plugin.xml.  This change in fact affects the file META-INF/MANIFEST.MF rather than plugin.xml.

To test the plugin I created a Run Configuration specifying "Eclipse Application".  This launches a second instance of Eclipse with my version of DDMS available as a Perspective.  Errors in my plugin code get printed to the Console of the first Eclipse instance.

Contributing source upstream

Followed instructions from here on.

Patch merged into head branch!
Subpages (1): Hacking guidelines
Comments