5 package org.chromium.sdk.internal.tools.v8; |
5 package org.chromium.sdk.internal.tools.v8; |
6 |
6 |
7 import java.util.ArrayList; |
7 import java.util.ArrayList; |
8 import java.util.Collections; |
8 import java.util.Collections; |
9 import java.util.List; |
9 import java.util.List; |
10 import java.util.concurrent.Semaphore; |
|
11 import java.util.concurrent.TimeUnit; |
10 import java.util.concurrent.TimeUnit; |
12 |
11 |
13 import org.chromium.sdk.CallbackSemaphore; |
12 import org.chromium.sdk.CallbackSemaphore; |
14 import org.chromium.sdk.SyncCallback; |
13 import org.chromium.sdk.SyncCallback; |
15 import org.chromium.sdk.JsValue.Type; |
14 import org.chromium.sdk.JsValue.Type; |
46 /** |
45 /** |
47 * The debug context in which the operations are performed. |
46 * The debug context in which the operations are performed. |
48 */ |
47 */ |
49 private final DebugSession debugSession; |
48 private final DebugSession debugSession; |
50 |
49 |
51 /** |
|
52 * A semaphore that prevents concurrent script reloading (which may effectively |
|
53 * double the efforts.) |
|
54 */ |
|
55 private final Semaphore scriptsReloadSemaphore = new Semaphore(1); |
|
56 |
|
57 public V8Helper(DebugSession debugSession) { |
50 public V8Helper(DebugSession debugSession) { |
58 this.debugSession = debugSession; |
51 this.debugSession = debugSession; |
59 } |
52 } |
60 |
53 |
61 /** |
54 public interface ScriptLoadCallback { |
62 * Reloads all normal scripts found in the page. First, all scripts without |
55 void success(); |
63 * their sources are retrieved to save bandwidth (script list change during a |
56 void failure(String message); |
64 * page lifetime is a relatively rare event.) If at least one script has been |
57 } |
65 * added, the script cache is dropped and re-populated with new scripts that |
58 |
66 * are re-requested together with their sources. |
59 /** |
67 * |
60 * Loads all scripts and stores them in ScriptManager. |
68 * @param callback to invoke when the script reloading has completed |
61 * @param callback to invoke when the script reloading has completed |
69 */ |
62 * @param syncCallback to invoke after callback whether it normally returned or threw an exception |
70 public void reloadAllScriptsAsync(V8CommandProcessor.V8HandlerCallback callback, |
63 */ |
71 SyncCallback syncCallback) { |
64 public static void reloadAllScriptsAsync(final DebugSession debugSession, |
72 final V8CommandProcessor.V8HandlerCallback finalCallback = callback != null |
65 final ScriptLoadCallback callback, SyncCallback syncCallback) { |
73 ? callback |
|
74 : V8CommandProcessor.V8HandlerCallback.NULL_CALLBACK; |
|
75 lock(); |
|
76 debugSession.sendMessageAsync( |
66 debugSession.sendMessageAsync( |
77 DebuggerMessageFactory.scripts(ScriptsMessage.SCRIPTS_NORMAL, true), |
67 DebuggerMessageFactory.scripts(ScriptsMessage.SCRIPTS_NORMAL, true), |
78 true, |
68 true, |
79 new V8CommandProcessor.V8HandlerCallback() { |
69 new V8CommandCallbackBase() { |
|
70 @Override |
80 public void failure(String message) { |
71 public void failure(String message) { |
81 unlock(); |
72 callback.failure(message); |
82 finalCallback.failure(message); |
|
83 } |
73 } |
84 |
74 |
85 public void messageReceived(CommandResponse response) { |
75 @Override |
86 SuccessCommandResponse successResponse = response.asSuccess(); |
76 public void success(SuccessCommandResponse successResponse) { |
87 |
|
88 // TODO(peter.rybin): add try/finally for unlock, with some error reporting probably. |
|
89 List<ScriptHandle> body; |
77 List<ScriptHandle> body; |
90 try { |
78 try { |
91 body = successResponse.getBody().asScripts(); |
79 body = successResponse.getBody().asScripts(); |
92 } catch (JsonProtocolParseException e) { |
80 } catch (JsonProtocolParseException e) { |
93 throw new RuntimeException(e); |
81 throw new RuntimeException(e); |
96 for (int i = 0; i < body.size(); ++i) { |
84 for (int i = 0; i < body.size(); ++i) { |
97 ScriptHandle scriptHandle = body.get(i); |
85 ScriptHandle scriptHandle = body.get(i); |
98 Long id = V8ProtocolUtil.getScriptIdFromResponse(scriptHandle); |
86 Long id = V8ProtocolUtil.getScriptIdFromResponse(scriptHandle); |
99 if (scriptManager.findById(id) == null && |
87 if (scriptManager.findById(id) == null && |
100 !ChromeDevToolSessionManager.JAVASCRIPT_VOID.equals(scriptHandle.source())) { |
88 !ChromeDevToolSessionManager.JAVASCRIPT_VOID.equals(scriptHandle.source())) { |
101 scriptManager.addScript( |
89 scriptManager.addScript(scriptHandle, successResponse.getRefs()); |
102 scriptHandle, |
|
103 successResponse.getRefs()); |
|
104 } |
90 } |
105 } |
91 } |
106 unlock(); |
92 callback.success(); |
107 finalCallback.messageReceived(response); |
|
108 } |
93 } |
109 }, |
94 }, |
110 syncCallback); |
95 syncCallback); |
111 } |
|
112 |
|
113 protected void lock() { |
|
114 try { |
|
115 scriptsReloadSemaphore.acquire(); |
|
116 } catch (InterruptedException e) { |
|
117 // consider it a successful acquisition |
|
118 } |
|
119 } |
|
120 |
|
121 protected void unlock() { |
|
122 scriptsReloadSemaphore.release(); |
|
123 } |
96 } |
124 |
97 |
125 /** |
98 /** |
126 * Gets all resolved locals for the call frame, caches scripts and objects in |
99 * Gets all resolved locals for the call frame, caches scripts and objects in |
127 * the scriptManager and handleManager. |
100 * the scriptManager and handleManager. |
220 |
193 |
221 private static ValueMirror createValueMirror(ValueHandle valueHandle) { |
194 private static ValueMirror createValueMirror(ValueHandle valueHandle) { |
222 String className = valueHandle.className(); |
195 String className = valueHandle.className(); |
223 Type type = JsDataTypeUtil.fromJsonTypeAndClassName(valueHandle.type(), className); |
196 Type type = JsDataTypeUtil.fromJsonTypeAndClassName(valueHandle.type(), className); |
224 if (type == null) { |
197 if (type == null) { |
225 throw new ValueLoadException("Bad value object"); |
198 type = Type.TYPE_OBJECT; |
226 } |
199 } |
227 String text = valueHandle.text(); |
200 String text = valueHandle.text(); |
228 return createMirrorFromLookup(valueHandle, type).getValueMirror(); |
201 return createMirrorFromLookup(valueHandle, type).getValueMirror(); |
229 } |
202 } |
230 |
203 |