private void OnInvokeFunction(CefBrowser browser, PluginMessage pluginMessage, JavaScriptPlugin handler) { var methodDescriptor = handler.Descriptor.Methods.Find(descriptor => descriptor.MethodName == pluginMessage.MemberName); IJavaScriptPluginCallback returnCallback = null; BrowserCallInfo parameterCallback = null; if (pluginMessage.V8CallbackId != Guid.Empty) { if (methodDescriptor.HasCallbackParameter) { // Create a second stored callback info which represents the V8 callback function itself // rather than the method that is being invoked now. This allows the callback function // to be passed to and invoked by multiple native methods that accept a callback parameter. parameterCallback = _pendingCallbacks.Get(pluginMessage.V8CallbackId); if (parameterCallback == null) { var parameterCallbackMessage = new PluginMessage { MessageId = pluginMessage.V8CallbackId, MessageType = PluginMessageType.ParameterCallback, PluginId = string.Empty, MemberName = string.Empty, BrowserId = pluginMessage.BrowserId, ContextId = pluginMessage.ContextId, FrameId = pluginMessage.FrameId, V8CallbackId = Guid.Empty }; parameterCallback = CreateAndAddCall(browser.Clone(), parameterCallbackMessage, null, null); } } var returnCallInfo = CreateAndAddCall(browser, pluginMessage, handler, parameterCallback); if (!handler.IsValid) { RemoveAndCancelCall(returnCallInfo); return; } returnCallback = returnCallInfo; } JArray callArgs = null; if (!string.IsNullOrEmpty(pluginMessage.Data)) { callArgs = JArray.Parse(pluginMessage.Data); } handler.InvokeFunction( _pluginManager, pluginMessage.BrowserId, pluginMessage.FrameId, pluginMessage.ContextId, pluginMessage.MemberName, new JArrayJavaScriptParameters(callArgs), returnCallback); }
public void RemoveEventListener(string eventName, IJavaScriptPluginCallback eventCallback) { ThrowIfDisposed(); JavaScriptEvent eventSubscription; if (_events.TryGetValue(eventName, out eventSubscription)) { eventSubscription.RemoveHandler(eventCallback); } }
public void AddHandler(IJavaScriptPluginCallback callback) { ThrowIfDisposed(); if (callback == null) { throw new ArgumentNullException("callback"); } _callbacks.TryAdd(callback.Identifier, callback); }
private static void InvokeReturnCallback(IJavaScriptPluginCallback callback, object data, int errorCode, string error) { try { callback.Invoke(data, errorCode, error); } catch (Exception e) { Logger.Error("Error invoking plugin return callback: " + e); } }
public void RemoveHandler(IJavaScriptPluginCallback callback) { ThrowIfDisposed(); if (callback == null) { throw new ArgumentNullException("callback"); } IJavaScriptPluginCallback removedCallback; _callbacks.TryRemove(callback.Identifier, out removedCallback); }
public bool AddEventListener(string eventName, IJavaScriptPluginCallback eventCallback) { ThrowIfDisposed(); JavaScriptEvent eventSubscription; if (_events.TryGetValue(eventName, out eventSubscription)) { eventSubscription.AddHandler(eventCallback); return(true); } return(false); }
public void InvokeFunction( IPluginManager pluginManager, int browserId, long frameId, int contextId, string methodName, IJavaScriptParameters parameters, IJavaScriptPluginCallback callback) { var invoker = CreateInvoker(pluginManager, browserId, frameId, contextId, methodName, parameters, callback); if (_callbackThread == CallbackThread.Main) { ParagonRuntime.MainThreadContext.Post(o => invoker(), null); } else { ThreadPool.QueueUserWorkItem(o => invoker()); } }
private Action CreateInvoker(IPluginManager pluginManager, int browserId, long frameId, int contextId, string methodName, IJavaScriptParameters parameters, IJavaScriptPluginCallback callback) { ThrowIfDisposed(); if (parameters == null) { throw new ArgumentNullException("parameters"); } MethodInfo method; if (!_methods.TryGetValue(methodName, out method)) { if (callback != null) { var msg = string.Format("Error executing {0} on plugin {1} - method not found", methodName, _pluginId); InvokeReturnCallback(callback, null, 0, msg); } } var nativeObject = NativeObject; if (nativeObject == null) { if (callback != null) { var msg = string.Format("Error executing {0} on plugin {1} - plugin object has been disposed", methodName, _pluginId); InvokeReturnCallback(callback, null, 0, msg); } } object[] arguments; var hasCallbackParameter = HasCallbackParameter(method); var methodParams = method.GetParameters(); var parameterDefinitions = hasCallbackParameter ? methodParams.Take(methodParams.Length - 1).ToArray() : methodParams; try { arguments = parameters.GetConvertedParameters(parameterDefinitions, pluginManager); if (hasCallbackParameter) { // Create a new args array with length + 1 so we can add the callback param to it. var args = new object[arguments.Length + 1]; Array.Copy(arguments, args, arguments.Length); // Extract the callback and wrap it. JavaScriptPluginCallback callbackParam = null; if (callback != null) { var parameterCallback = callback.GetParameterCallback(); if (parameterCallback != null) { callbackParam = parameterCallback.Invoke; } } // Add the wrapped callback to the args list. args[args.Length - 1] = callbackParam; arguments = args; } } catch (Exception ex) { Logger.Error("Error converting plugin invocation parameters: " + ex); if (callback != null) { InvokeReturnCallback(callback, null, -1, ex.Message); } return(null); } var invoke = new Action( () => { using (PluginExecutionContext.Create(browserId, contextId, frameId)) { object result = null; var errorCode = 0; var error = string.Empty; try { result = method.Invoke(nativeObject, arguments); } catch (Exception e) { while (e is TargetInvocationException) { e = e.InnerException; } errorCode = -1; error = e.Message; Logger.Error("Error executing plugin method: " + e); } if (callback != null) { InvokeReturnCallback(callback, result, errorCode, error); } } }); return(invoke); }
public void InvokeFunctionDirect(IPluginManager pluginManager, int browserId, long frameId, int contextId, string methodName, IJavaScriptParameters parameters, IJavaScriptPluginCallback callback) { var invoker = CreateInvoker(pluginManager, browserId, frameId, contextId, methodName, parameters, callback); invoker(); }