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);
        }
コード例 #2
0
        public void RemoveEventListener(string eventName, IJavaScriptPluginCallback eventCallback)
        {
            ThrowIfDisposed();
            JavaScriptEvent eventSubscription;

            if (_events.TryGetValue(eventName, out eventSubscription))
            {
                eventSubscription.RemoveHandler(eventCallback);
            }
        }
コード例 #3
0
        public void AddHandler(IJavaScriptPluginCallback callback)
        {
            ThrowIfDisposed();

            if (callback == null)
            {
                throw new ArgumentNullException("callback");
            }

            _callbacks.TryAdd(callback.Identifier, callback);
        }
コード例 #4
0
 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);
     }
 }
コード例 #5
0
        public void RemoveHandler(IJavaScriptPluginCallback callback)
        {
            ThrowIfDisposed();

            if (callback == null)
            {
                throw new ArgumentNullException("callback");
            }

            IJavaScriptPluginCallback removedCallback;

            _callbacks.TryRemove(callback.Identifier, out removedCallback);
        }
コード例 #6
0
        public bool AddEventListener(string eventName, IJavaScriptPluginCallback eventCallback)
        {
            ThrowIfDisposed();
            JavaScriptEvent eventSubscription;

            if (_events.TryGetValue(eventName, out eventSubscription))
            {
                eventSubscription.AddHandler(eventCallback);
                return(true);
            }

            return(false);
        }
コード例 #7
0
        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());
            }
        }
コード例 #8
0
        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);
        }
コード例 #9
0
        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();
        }