Skip to content

Commit cb123c2

Browse files
committed
added debugger code and changes to gradle build scripts
1 parent 03c2efe commit cb123c2

11 files changed

Lines changed: 455 additions & 57 deletions

File tree

.gitignore

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
mode/processing-core.zip
2-
mode/mode/*.jar
2+
mode/mode/AndroidMode.jar
3+
mode/mode/gradle-tooling-api*
4+
mode/mode/slf4j*
35

46
mode/libraries/vr/library
57
mode/tools/SDKUpdated/tool

build.gradle

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ allprojects {
3232
ext.slf4jVersion = '1.7.10'
3333
ext.gradlewVersion = '4.4.1'
3434
ext.toolsLibVersion = '26.0.0-dev'
35+
ext.jdtVersion = '3.11.100'
3536

3637
Properties modeProperties = new Properties()
3738
modeProperties.load(project.rootProject.file("mode/mode.properties").newDataInputStream())
@@ -93,9 +94,11 @@ task dist {
9394
// Copy assets to build dir
9495
FileUtils.copyDirectory(file("mode/templates"), file("${root}/templates"))
9596
FileUtils.copyDirectory(file("mode/examples"), file("${root}/examples"))
96-
FileUtils.copyDirectory(file("mode/icons"), file("${root}/icons"))
97-
FileUtils.copyDirectory(file("mode/mode"), file("${root}/mode"))
97+
FileUtils.copyDirectory(file("mode/icons"), file("${root}/icons"))
9898
FileUtils.copyDirectory(file("mode/theme"), file("${root}/theme"))
99+
FileUtils.copyDirectory(file("mode/mode"), file("${root}/mode"))
100+
delete "${root}/mode/jdi.jar"
101+
delete "${root}/mode/jdimodel.jar"
99102

100103
Files.copy(file("mode/processing-core.zip").toPath(),
101104
file("${root}/processing-core.zip").toPath(), REPLACE_EXISTING);

mode/build.gradle

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,21 @@ import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;
77
// https://stackoverflow.com/a/43602463
88
configurations {
99
compile.extendsFrom compileAndCopy
10+
compile.extendsFrom compileAndExtract
1011
}
1112

1213
dependencies {
1314
compile group: "org.processing", name: "core", version: "${processingVersion}"
1415
compile group: "org.processing", name: "pde", version: "${processingVersion}"
1516
compile group: "org.processing", name: "java-mode", version: "${processingVersion}"
1617

18+
compileAndExtract "org.eclipse.jdt:org.eclipse.jdt.debug:${jdtVersion}"
19+
1720
compileAndCopy "org.gradle:gradle-tooling-api:${toolingVersion}"
1821
compileAndCopy "org.slf4j:slf4j-api:${slf4jVersion}"
19-
compileAndCopy "org.slf4j:slf4j-simple:${slf4jVersion}"
22+
compileAndCopy "org.slf4j:slf4j-simple:${slf4jVersion}"
23+
24+
compile fileTree(include: ["jdi.jar", "jdimodel.jar"], dir: 'mode')
2025
}
2126

2227
// This task copies the gradle tooling jar into the mode folder
@@ -34,6 +39,16 @@ sourceSets {
3439
}
3540
}
3641

42+
task getjdi(type: Copy) {
43+
// This task extracts the jar files inside org.eclipse.jdt.debug, which are
44+
// jdi.jar and jdimodel.jar and needed to build the debugger.
45+
from(zipTree(configurations.compileAndExtract.files[0])) {
46+
include '**/*.jar'
47+
exclude 'META-INF'
48+
}
49+
into "mode"
50+
}
51+
3752
task permissions(type:Exec) {
3853
// This task retrieves the latest list of Android permissions and adds them
3954
// to the Permissions.java file. The python scripts requries BeautifulSoup

mode/mode/jdi.jar

73 KB
Binary file not shown.

mode/mode/jdimodel.jar

924 KB
Binary file not shown.
Lines changed: 210 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,210 @@
1+
package processing.mode.android;
2+
3+
import com.sun.jdi.*;
4+
import com.sun.jdi.event.*;
5+
import com.sun.jdi.request.ClassPrepareRequest;
6+
import com.sun.jdi.request.EventRequestManager;
7+
import com.sun.jdi.request.ModificationWatchpointRequest;
8+
import processing.mode.java.Debugger;
9+
import processing.mode.java.debug.LineBreakpoint;
10+
import processing.mode.java.debug.LineID;
11+
12+
import java.io.IOException;
13+
import java.util.List;
14+
15+
public class AndroidDebugger extends Debugger {
16+
/// editor window, acting as main view
17+
protected AndroidEditor editor;
18+
protected AndroidRunner runtime;
19+
protected AndroidMode androidMode;
20+
21+
protected boolean isEnabled;
22+
23+
private static final int TCP_PORT = 7777;
24+
25+
private String pkgName = "";
26+
private String sketchClassName = "";
27+
28+
public static final String FIELD_NAME = "mouseX";
29+
30+
public AndroidDebugger(AndroidEditor editor, AndroidMode androidMode) {
31+
super(editor);
32+
this.editor = editor;
33+
this.androidMode = androidMode;
34+
}
35+
36+
public boolean isEnabled() {
37+
return isEnabled;
38+
}
39+
40+
public void toggleDebug() {
41+
isEnabled = !isEnabled;
42+
}
43+
44+
@Override
45+
public AndroidEditor getEditor() {
46+
return editor;
47+
}
48+
49+
public synchronized void startDebug(AndroidRunner runner, Device device) {
50+
//stopDebug(); // stop any running sessions
51+
if (isStarted()) {
52+
return; // do nothing
53+
}
54+
55+
runtime = runner;
56+
pkgName = runner.build.getPackageName();
57+
sketchClassName = runner.build.getSketchClassName();
58+
59+
try {
60+
device.forwardPort(TCP_PORT);
61+
62+
// connect
63+
System.out.println("\n\n\n:debugger:Attaching Debugger");
64+
VirtualMachine vm = runner.connectVirtualMachine(TCP_PORT);
65+
66+
// set watch field on already loaded classes
67+
List<ReferenceType> referenceTypes = vm.classesByName(pkgName + "." + sketchClassName);
68+
69+
for (ReferenceType refType : referenceTypes) {
70+
addFieldWatch(vm, refType);
71+
72+
// Adding breakpoint at line 27
73+
// try {
74+
// List<Location> locations = refType.locationsOfLine(28);
75+
// if (locations.isEmpty()){
76+
// System.out.println("no location found for line 27");
77+
// } else {
78+
// BreakpointRequest bpr = vm.eventRequestManager().createBreakpointRequest(locations.get(0));
79+
// bpr.enable();
80+
// }
81+
// } catch (AbsentInformationException e) {
82+
// e.printStackTrace();
83+
// }
84+
}
85+
// watch for loaded classes
86+
addClassWatch(vm);
87+
88+
// resume the vm
89+
vm.resume();
90+
91+
// start receiving vm events
92+
VMEventReader eventThread = new VMEventReader(vm.eventQueue(), vmEventListener);
93+
eventThread.start();
94+
} catch (IOException e) {
95+
e.printStackTrace();
96+
} catch (InterruptedException e) {
97+
e.printStackTrace();
98+
}
99+
}
100+
101+
/**
102+
* Watch all classes ({@value sketchClassName}) variable
103+
*/
104+
private void addClassWatch(VirtualMachine vm) {
105+
EventRequestManager erm = vm.eventRequestManager();
106+
ClassPrepareRequest classPrepareRequest = erm.createClassPrepareRequest();
107+
classPrepareRequest.addClassFilter(sketchClassName);
108+
classPrepareRequest.setEnabled(true);
109+
}
110+
111+
/**
112+
* Watch field ({@value FIELD_NAME})
113+
*/
114+
private void addFieldWatch(VirtualMachine vm,
115+
ReferenceType refType) {
116+
EventRequestManager erm = vm.eventRequestManager();
117+
Field field = refType.fieldByName(FIELD_NAME);
118+
ModificationWatchpointRequest modificationWatchpointRequest = erm.createModificationWatchpointRequest(field);
119+
modificationWatchpointRequest.setEnabled(true);
120+
}
121+
122+
@Override
123+
public VirtualMachine vm() {
124+
if (runtime != null) {
125+
return runtime.vm();
126+
}
127+
return null;
128+
}
129+
130+
/**
131+
* Get the breakpoint on a certain line, if set.
132+
*
133+
* @param line the line to get the breakpoint from
134+
* @return the breakpoint, or null if no breakpoint is set on the specified
135+
* line.
136+
*/
137+
LineBreakpoint breakpointOnLine(LineID line) {
138+
for (LineBreakpoint bp : breakpoints) {
139+
if (bp.isOnLine(line)) {
140+
return bp;
141+
}
142+
}
143+
return null;
144+
}
145+
146+
synchronized void toggleBreakpoint(int lineIdx) {
147+
LineID line = editor.getLineIDInCurrentTab(lineIdx);
148+
int index = line.lineIdx();
149+
if (hasBreakpoint(line)) {
150+
removeBreakpoint(index);
151+
} else {
152+
// Make sure the line contains actual code before setting the break
153+
// https://github.com/processing/processing/issues/3765
154+
if (editor.getLineText(index).trim().length() != 0) {
155+
setBreakpoint(index);
156+
}
157+
}
158+
}
159+
160+
/**
161+
* Set a breakpoint on a line in the current tab.
162+
*
163+
* @param lineIdx the line index (0-based) of the current tab to set the
164+
* breakpoint on
165+
*/
166+
synchronized void setBreakpoint(int lineIdx) {
167+
setBreakpoint(editor.getLineIDInCurrentTab(lineIdx));
168+
}
169+
170+
171+
synchronized void setBreakpoint(LineID line) {
172+
// do nothing if we are kinda busy
173+
if (isStarted() && !isPaused()) {
174+
return;
175+
}
176+
// do nothing if there already is a breakpoint on this line
177+
if (hasBreakpoint(line)) {
178+
return;
179+
}
180+
breakpoints.add(new LineBreakpoint(line, this));
181+
}
182+
183+
184+
/**
185+
* Remove a breakpoint from the current line (if set).
186+
*/
187+
synchronized void removeBreakpoint() {
188+
removeBreakpoint(editor.getCurrentLineID().lineIdx());
189+
}
190+
191+
192+
/**
193+
* Remove a breakpoint from a line in the current tab.
194+
*
195+
* @param lineIdx the line index (0-based) in the current tab to remove the
196+
* breakpoint from
197+
*/
198+
void removeBreakpoint(int lineIdx) {
199+
// do nothing if we are kinda busy
200+
if (isBusy()) {
201+
return;
202+
}
203+
204+
LineBreakpoint bp = breakpointOnLine(editor.getLineIDInCurrentTab(lineIdx));
205+
if (bp != null) {
206+
bp.remove();
207+
breakpoints.remove(bp);
208+
}
209+
}
210+
}

mode/src/processing/mode/android/AndroidEditor.java

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
import processing.app.ui.EditorToolbar;
3434
import processing.app.ui.Toolkit;
3535
import processing.mode.java.JavaEditor;
36+
import processing.mode.java.debug.LineID;
3637
import processing.mode.java.preproc.PdePreprocessor;
3738

3839
import javax.swing.*;
@@ -59,6 +60,8 @@ public class AndroidEditor extends JavaEditor {
5960
private JMenu androidMenu;
6061

6162
private int appComponent;
63+
64+
private AndroidDebugger debugger;
6265

6366
private Settings settings;
6467
private AndroidMode androidMode;
@@ -77,12 +80,15 @@ protected AndroidEditor(Base base, String path, EditorState state,
7780
androidMode = (AndroidMode) mode;
7881
androidMode.resetUserSelection();
7982
androidMode.checkSDK(this);
80-
83+
84+
debugger = new AndroidDebugger(this, androidMode);
85+
super.debugger = debugger;
86+
8187
androidTools = loadAndroidTools();
8288
addToolsToMenu();
8389

8490
loadModeSettings();
85-
}
91+
}
8692

8793
@Override
8894
public PdePreprocessor createPreprocessor(final String sketchName) {
@@ -155,7 +161,7 @@ public void actionPerformed(ActionEvent e) {
155161
handleStop();
156162
}
157163
});
158-
return buildSketchMenu(new JMenuItem[] { runItem, presentItem, stopItem });
164+
return buildSketchMenu(new JMenuItem[] { buildDebugMenu(), runItem, presentItem, stopItem });
159165
}
160166

161167

@@ -388,6 +394,26 @@ public void handleStop() {
388394
androidMode.handleStop(this);
389395
}
390396

397+
@Override
398+
public AndroidDebugger getDebugger() {
399+
return debugger;
400+
}
401+
402+
@Override
403+
public void toggleDebug() {
404+
super.toggleDebug();
405+
debugger.toggleDebug();
406+
}
407+
408+
@Override
409+
public void toggleBreakpoint(int lineIndex) {
410+
debugger.toggleBreakpoint(lineIndex);
411+
}
412+
413+
@Override
414+
protected LineID getCurrentLineID() {
415+
return super.getCurrentLineID();
416+
}
391417

392418
/**
393419
* Create a release build of the sketch and have its apk files ready.

mode/src/processing/mode/android/AndroidMode.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -319,9 +319,9 @@ public void handleRunDevice(Sketch sketch, AndroidEditor editor,
319319
}
320320

321321
int comp = build.getAppComponent();
322-
Future<Device> dev = Devices.getInstance().getHardware();
322+
Future<Device> dev = Devices.getInstance().getHardware();
323323
runner = new AndroidRunner(build, listener);
324-
if (runner.launch(dev, comp, false)) {
324+
if (runner.launch(dev, comp, false)) {
325325
showPostBuildMessage(comp);
326326
}
327327
}

0 commit comments

Comments
 (0)