org.chromium.sdk/src/org/chromium/sdk/internal/tools/v8/V8Helper.java
changeset 276 f2f4a1259de8
parent 2 e4420d2515f1
child 355 8726e95bcbba
equal deleted inserted replaced
275:12c2ea2194c7 276:f2f4a1259de8
     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