| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 package org.chromium.sdk.internal.wip; | |
| 6 | |
| 7 import java.util.ArrayList; | |
| 8 import java.util.Collection; | |
| 9 import java.util.HashMap; | |
| 10 import java.util.HashSet; | |
| 11 import java.util.List; | |
| 12 import java.util.Map; | |
| 13 import java.util.Set; | |
| 14 import java.util.concurrent.atomic.AtomicInteger; | |
| 15 | |
| 16 import org.chromium.sdk.Breakpoint; | |
| 17 import org.chromium.sdk.Breakpoint.Target; | |
| 18 import org.chromium.sdk.JavascriptVm.BreakpointCallback; | |
| 19 import org.chromium.sdk.RelayOk; | |
| 20 import org.chromium.sdk.SyncCallback; | |
| 21 import org.chromium.sdk.TextStreamPosition; | |
| 22 import org.chromium.sdk.internal.wip.protocol.input.debugger.BreakpointResolvedE
ventData; | |
| 23 import org.chromium.sdk.util.RelaySyncCallback; | |
| 24 | |
| 25 /** | |
| 26 * A manager that works as factory for breakpoints. | |
| 27 */ | |
| 28 public class WipBreakpointManager { | |
| 29 private final WipTabImpl tabImpl; | |
| 30 private final AtomicInteger breakpointUniqueId = new AtomicInteger(0); | |
| 31 private final Db db = new Db(); | |
| 32 | |
| 33 WipBreakpointManager(WipTabImpl tabImpl) { | |
| 34 this.tabImpl = tabImpl; | |
| 35 } | |
| 36 | |
| 37 RelayOk setBreakpoint(Breakpoint.Target target, final int line, final int colu
mn, | |
| 38 final boolean enabled, String condition, | |
| 39 final BreakpointCallback callback, SyncCallback syncCallback) { | |
| 40 | |
| 41 int sdkId = breakpointUniqueId.getAndAdd(1); | |
| 42 | |
| 43 final WipBreakpointImpl breakpointImpl = new WipBreakpointImpl(this, sdkId, | |
| 44 target, line, column, condition, enabled); | |
| 45 | |
| 46 db.addBreakpoint(breakpointImpl); | |
| 47 | |
| 48 if (enabled) { | |
| 49 if (condition == null) { | |
| 50 condition = ""; | |
| 51 } | |
| 52 | |
| 53 WipBreakpointImpl.SetBreakpointCallback wrappedCallback = | |
| 54 new WipBreakpointImpl.SetBreakpointCallback() { | |
| 55 @Override | |
| 56 public void onSuccess(String protocolId, | |
| 57 Collection<WipBreakpointImpl.ActualLocation> actualLocations) { | |
| 58 breakpointImpl.setRemoteData(protocolId, actualLocations); | |
| 59 if (callback != null) { | |
| 60 callback.success(breakpointImpl); | |
| 61 } | |
| 62 } | |
| 63 | |
| 64 @Override | |
| 65 public void onFailure(Exception exception) { | |
| 66 if (callback != null) { | |
| 67 callback.failure(exception.getMessage()); | |
| 68 } | |
| 69 } | |
| 70 }; | |
| 71 | |
| 72 return WipBreakpointImpl.sendSetBreakpointRequest(target, line, column, co
ndition, | |
| 73 wrappedCallback, syncCallback, tabImpl.getCommandProcessor()); | |
| 74 } else { | |
| 75 callback.success(breakpointImpl); | |
| 76 return RelaySyncCallback.finish(syncCallback); | |
| 77 } | |
| 78 } | |
| 79 | |
| 80 Db getDb() { | |
| 81 return db; | |
| 82 } | |
| 83 | |
| 84 void clearNonProvisionalBreakpoints() { | |
| 85 db.visitAllBreakpoints(new Db.Visitor<Void>() { | |
| 86 @Override | |
| 87 public Void visitAllBreakpoints(Set<WipBreakpointImpl> breakpoints) { | |
| 88 List<WipBreakpointImpl> deleteList = new ArrayList<WipBreakpointImpl>(); | |
| 89 for (WipBreakpointImpl breakpoint : breakpoints) { | |
| 90 if (breakpoint.getTarget().accept(IS_SCRIPT_ID_VISITOR)) { | |
| 91 deleteList.add(breakpoint); | |
| 92 } else { | |
| 93 breakpoint.clearActualLocations(); | |
| 94 } | |
| 95 } | |
| 96 for (WipBreakpointImpl breakpoint : deleteList) { | |
| 97 breakpoint.deleteSelfFromDb(); | |
| 98 } | |
| 99 return null; | |
| 100 } | |
| 101 }); | |
| 102 } | |
| 103 | |
| 104 private static final Breakpoint.Target.Visitor<Boolean> IS_SCRIPT_ID_VISITOR = | |
| 105 new Breakpoint.Target.Visitor<Boolean>() { | |
| 106 @Override | |
| 107 public Boolean visitScriptName(String scriptName) { | |
| 108 return Boolean.FALSE; | |
| 109 } | |
| 110 | |
| 111 @Override | |
| 112 public Boolean visitScriptId(Object scriptId) { | |
| 113 return Boolean.TRUE; | |
| 114 } | |
| 115 | |
| 116 @Override | |
| 117 public Boolean visitUnknown(Target target) { | |
| 118 return Boolean.FALSE; | |
| 119 } | |
| 120 }; | |
| 121 | |
| 122 WipCommandProcessor getCommandProcessor() { | |
| 123 return tabImpl.getCommandProcessor(); | |
| 124 } | |
| 125 | |
| 126 Collection<WipBreakpointImpl> getAllBreakpoints() { | |
| 127 return db.visitAllBreakpoints(new Db.Visitor<Collection<WipBreakpointImpl>>(
) { | |
| 128 @Override | |
| 129 public Collection<WipBreakpointImpl> visitAllBreakpoints( | |
| 130 Set<WipBreakpointImpl> breakpoints) { | |
| 131 return new ArrayList<WipBreakpointImpl>(breakpoints); | |
| 132 } | |
| 133 }); | |
| 134 } | |
| 135 | |
| 136 void breakpointReportedResolved(BreakpointResolvedEventData eventData) { | |
| 137 String breakpointId = eventData.breakpointId(); | |
| 138 WipBreakpointImpl breakpoint = db.getBreakpoint(breakpointId); | |
| 139 if (breakpoint == null) { | |
| 140 throw new RuntimeException("Failed to find breakpoint by id: " + breakpoin
tId); | |
| 141 } | |
| 142 breakpoint.addResolvedLocation(eventData.location()); | |
| 143 } | |
| 144 | |
| 145 // Accessed from Dispatch thread. | |
| 146 public Collection<? extends Breakpoint> findRelatedBreakpoints( | |
| 147 WipContextBuilder.WipDebugContextImpl.CallFrameImpl topFrame) { | |
| 148 TextStreamPosition position = topFrame.getStatementStartPosition(); | |
| 149 int line = position.getLine(); | |
| 150 int column = position.getColumn(); | |
| 151 | |
| 152 String scriptId = topFrame.getSourceId(); | |
| 153 final WipBreakpointImpl.ActualLocation location = | |
| 154 new WipBreakpointImpl.ActualLocation(scriptId, line, Long.valueOf(column
)); | |
| 155 | |
| 156 return db.visitAllBreakpoints(new Db.Visitor<List<Breakpoint>>() { | |
| 157 @Override | |
| 158 public List<Breakpoint> visitAllBreakpoints(Set<WipBreakpointImpl> breakpo
ints) { | |
| 159 List<Breakpoint> result = new ArrayList<Breakpoint>(1); | |
| 160 for (WipBreakpointImpl breakpoint : breakpoints) { | |
| 161 if (breakpoint.getActualLocations().contains(location)) { | |
| 162 result.add(breakpoint); | |
| 163 } | |
| 164 } | |
| 165 return result; | |
| 166 } | |
| 167 }); | |
| 168 } | |
| 169 | |
| 170 /** | |
| 171 * Breakpoint data-base. Keeps track of all instances and their protocol-id ->
instance mapping. | |
| 172 * The name implies that it doesn't manage anything, only stores data. | |
| 173 */ | |
| 174 static class Db { | |
| 175 // Accessed from any thread. | |
| 176 private final Set<WipBreakpointImpl> breakpoints = new HashSet<WipBreakpoint
Impl>(); | |
| 177 | |
| 178 // Access from Dispatch thread only. | |
| 179 private final Map<String, WipBreakpointImpl> idToBreakpoint = | |
| 180 new HashMap<String, WipBreakpointImpl>(); | |
| 181 | |
| 182 void addBreakpoint(WipBreakpointImpl breakpoint) { | |
| 183 synchronized (breakpoints) { | |
| 184 breakpoints.add(breakpoint); | |
| 185 } | |
| 186 } | |
| 187 | |
| 188 void removeBreakpoint(WipBreakpointImpl breakpoint) { | |
| 189 synchronized (breakpoints) { | |
| 190 breakpoints.remove(breakpoint); | |
| 191 } | |
| 192 } | |
| 193 | |
| 194 void setIdMapping(WipBreakpointImpl breakpoint, | |
| 195 String protocolId) { | |
| 196 if (protocolId == null) { | |
| 197 idToBreakpoint.remove(protocolId); | |
| 198 } else { | |
| 199 idToBreakpoint.put(protocolId, breakpoint); | |
| 200 } | |
| 201 } | |
| 202 | |
| 203 WipBreakpointImpl getBreakpoint(String breakpointId) { | |
| 204 return idToBreakpoint.get(breakpointId); | |
| 205 } | |
| 206 | |
| 207 /** | |
| 208 * Gives a synchronized access to all breakpoints. | |
| 209 */ | |
| 210 <R> R visitAllBreakpoints(Visitor<R> visitor) { | |
| 211 synchronized (breakpoints) { | |
| 212 return visitor.visitAllBreakpoints(breakpoints); | |
| 213 } | |
| 214 } | |
| 215 | |
| 216 interface Visitor<R> { | |
| 217 R visitAllBreakpoints(Set<WipBreakpointImpl> breakpoints); | |
| 218 } | |
| 219 } | |
| 220 } | |
| OLD | NEW |