Last active
February 28, 2016 15:15
-
-
Save SignpostMarv/ebd17ab0ebf102daff22 to your computer and use it in GitHub Desktop.
dynamicish crosswalk .net extension api
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Based on https://github.com/crosswalk-project/tizen-extensions-crosswalk/blob/56953350a1ac0196183a51a5682d9fb9a388ea64/src/nfc/nfc_api.js | |
var g_next_async_call_id = 1; | |
var g_async_calls = {}; | |
function AsyncCall(resolve, reject) { | |
this.resolve = resolve || function placeholderRes(res) { | |
console.log(res); | |
}; | |
this.reject = reject || function placeholderRej(err) { | |
console.error(err); | |
}; | |
} | |
function createPromise(msg) { | |
var promise = new Promise(function (resolve, reject) { | |
g_async_calls[g_next_async_call_id] = new AsyncCall(resolve, reject); | |
}); | |
msg.asyncCallId = g_next_async_call_id; | |
extension.postMessage(JSON.stringify(msg)); | |
++g_next_async_call_id; | |
return promise; | |
} | |
extension.setMessageListener(function (json) { | |
document.body.appendChild(document.createTextNode(json)); | |
}); | |
exports = new Promise(function (resolve, reject) { | |
try { | |
extension.setMessageListener(function handleMsg(json) { | |
try { | |
var msg = JSON.parse(json); | |
var methods = []; | |
var api = {}; | |
console.log(msg); | |
if (msg instanceof Array) { | |
if (msg.length < 1) { | |
reject(new Error('No API Methods available!: ' + json)); | |
} else { | |
methods = msg.filter(function filterMsg(maybeMethod) { | |
return (typeof (maybeMethod) === 'string'); | |
}); | |
if (methods.length !== msg.length) { | |
reject(new Error('API Method length mismatch! Found ' + methods.length + ', expected ' + msg.length + '! :' + json)); | |
} else { | |
methods.forEach(function feMethod(methodName) { | |
api[methodName] = function apiMethod() { | |
return createPromise({ | |
method: methodName, | |
arguments: arguments, | |
}); | |
}; | |
}); | |
extension.setMessageListener(function handleMsg(json) { | |
var msg = JSON.parse(json); | |
if ( | |
typeof (msg) === 'object' && | |
Object.keys(msg).indexOf('asyncCallId') >= 0 && | |
typeof (g_async_calls[msg.asyncCallId]) !== 'undefined' && | |
g_async_calls[msg.asyncCallId] instanceof AsyncCall | |
) { | |
if (Object.keys(msg).indexOf('success') < 0) { | |
g_async_calls[msg.asyncCallId].reject(msg); | |
} else { | |
g_async_calls[msg.asyncCallId].resolve(msg); | |
} | |
delete g_async_calls[msg.asyncCallId]; | |
} else { | |
console.error('Unexpected message receieved: ' + json); | |
} | |
}); | |
resolve(api); | |
} | |
} | |
} else { | |
reject(new Error('JSON was not an array! :' + json)); | |
} | |
} catch (err) { | |
reject(err); | |
} | |
}); | |
extension.postMessage("GETAPI"); | |
} catch (err) { | |
reject(err); | |
} | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
echo.catch( | |
function(err){ | |
console.error(err); | |
} | |
).then( | |
function(api){ | |
api.echo('foo', 'bar').then( | |
function(resp){ | |
console.log(resp); | |
} | |
).catch(function(err){ | |
console.error(err); | |
}); | |
} | |
); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"devDependencies": { | |
"crosswalk-app-tools": "^0.9.1" | |
}, | |
"scripts": { | |
"xwalk-create-windows": "mkdir xwalk && cd xwalk && crosswalk-app create org.crosswalkProject.windows --platform=windows && mv org.crosswalkProject.windows windows" | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="utf-8"?> | |
<packages> | |
<package id="Newtonsoft.Json" version="8.0.2" targetFramework="net45" /> | |
</packages> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" ?> | |
<Prebuild version="1.10" xmlns="http://dnpb.sourceforge.net/schemas/prebuild-1.10.xsd"> | |
<Solution activeConfig="Debug" name="xwalk_dotnet" path="./"> | |
<Configuration name="Debug"> | |
<Options> | |
<CompilerDefines>TRACE;DEBUG</CompilerDefines> | |
<OptimizeCode>false</OptimizeCode> | |
<CheckUnderflowOverflow>false</CheckUnderflowOverflow> | |
<AllowUnsafe>true</AllowUnsafe> | |
<WarningLevel>4</WarningLevel> | |
<WarningsAsErrors>false</WarningsAsErrors> | |
<SuppressWarnings/> | |
<OutputPath>bin</OutputPath> | |
<DebugInformation>true</DebugInformation> | |
<IncrementalBuild>true</IncrementalBuild> | |
<NoStdLib>false</NoStdLib> | |
</Options> | |
</Configuration> | |
<Configuration name="Release"> | |
<Options> | |
<CompilerDefines>TRACE</CompilerDefines> | |
<OptimizeCode>true</OptimizeCode> | |
<CheckUnderflowOverflow>false</CheckUnderflowOverflow> | |
<AllowUnsafe>true</AllowUnsafe> | |
<WarningLevel>4</WarningLevel> | |
<WarningsAsErrors>false</WarningsAsErrors> | |
<SuppressWarnings/> | |
<OutputPath>bin</OutputPath> | |
<DebugInformation>false</DebugInformation> | |
<IncrementalBuild>true</IncrementalBuild> | |
<NoStdLib>false</NoStdLib> | |
</Options> | |
</Configuration> | |
<Project frameworkVersion="v4_5" name="xwalk_dotnet" path="./" type="Library"> | |
<Configuration name="Debug"> | |
<Options> | |
<OutputPath>xwalk/windows/prj/windows/</OutputPath> | |
</Options> | |
</Configuration> | |
<Configuration name="Release"> | |
<Options> | |
<OutputPath>xwalk/windows/prj/windows/</OutputPath> | |
</Options> | |
</Configuration> | |
<ReferencePath>./cs/libs/</ReferencePath> | |
<Reference name="Microsoft.CSharp"/> | |
<Reference name="System" /> | |
<Reference name="System.Core"/> | |
<Reference name="System.Reflection"/> | |
<Reference name="Newtonsoft.Json" localCopy="true"/> | |
<Files> | |
<Match pattern="./cs/*.cs" recurse="true"/> | |
<Match pattern="Properties/*.resx" recurse="false"/> | |
</Files> | |
</Project> | |
</Solution> | |
</Prebuild> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="utf-8"?> | |
<root> | |
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> | |
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" /> | |
<xsd:element name="root" msdata:IsDataSet="true"> | |
<xsd:complexType> | |
<xsd:choice maxOccurs="unbounded"> | |
<xsd:element name="metadata"> | |
<xsd:complexType> | |
<xsd:sequence> | |
<xsd:element name="value" type="xsd:string" minOccurs="0" /> | |
</xsd:sequence> | |
<xsd:attribute name="name" use="required" type="xsd:string" /> | |
<xsd:attribute name="type" type="xsd:string" /> | |
<xsd:attribute name="mimetype" type="xsd:string" /> | |
<xsd:attribute ref="xml:space" /> | |
</xsd:complexType> | |
</xsd:element> | |
<xsd:element name="assembly"> | |
<xsd:complexType> | |
<xsd:attribute name="alias" type="xsd:string" /> | |
<xsd:attribute name="name" type="xsd:string" /> | |
</xsd:complexType> | |
</xsd:element> | |
<xsd:element name="data"> | |
<xsd:complexType> | |
<xsd:sequence> | |
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> | |
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" /> | |
</xsd:sequence> | |
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" /> | |
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" /> | |
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" /> | |
<xsd:attribute ref="xml:space" /> | |
</xsd:complexType> | |
</xsd:element> | |
<xsd:element name="resheader"> | |
<xsd:complexType> | |
<xsd:sequence> | |
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> | |
</xsd:sequence> | |
<xsd:attribute name="name" type="xsd:string" use="required" /> | |
</xsd:complexType> | |
</xsd:element> | |
</xsd:choice> | |
</xsd:complexType> | |
</xsd:element> | |
</xsd:schema> | |
<resheader name="resmimetype"> | |
<value>text/microsoft-resx</value> | |
</resheader> | |
<resheader name="version"> | |
<value>2.0</value> | |
</resheader> | |
<resheader name="reader"> | |
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> | |
</resheader> | |
<resheader name="writer"> | |
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> | |
</resheader> | |
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" /> | |
<data name="api" type="System.Resources.ResXFileRef, System.Windows.Forms"> | |
<value>..\cs\api.js;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252</value> | |
</data> | |
</root> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Prebuild.exe /target vs2010 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Copyright (c) 2015 Intel Corporation. All rights reserved. | |
// Use of this source code is governed by a BSD-style license that can be | |
// found in the LICENSE file. | |
using System; | |
using System.Collections.Generic; | |
namespace xwalk | |
{ | |
public class XWalkExtension | |
{ | |
public XWalkExtension() | |
{ | |
XWalkExtensionInstance.InstanceReady += (sender, e) => | |
{ | |
((XWalkExtensionInstance)sender).RegisterApiMethods(typeof(XWalkExtension)); | |
}; | |
} | |
public String ExtensionName() | |
{ | |
return "echo"; | |
} | |
public String ExtensionAPI() | |
{ | |
return xwalk_dotnet.Properties.Resources.api; | |
} | |
[XWalkExtensionMethod("echo")] | |
public static Dictionary<string, object> echoResponse(Dictionary<string, object> message) | |
{ | |
return message; | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Copyright (c) 2015 Intel Corporation. All rights reserved. | |
// Use of this source code is governed by a BSD-style license that can be | |
// found in the LICENSE file. | |
using Newtonsoft.Json; | |
using System; | |
using System.Collections.Generic; | |
using System.Reflection; | |
using System.Linq; | |
using System.Linq.Expressions; | |
namespace xwalk | |
{ | |
public class XWalkExtensionInstance | |
{ | |
public static EventHandler InstanceReady; | |
private int addinsCount = 0; | |
private Exception addinsException = null; | |
public XWalkExtensionInstance(dynamic native) | |
{ | |
native_ = native; | |
InstanceReady.Invoke(this, null); | |
} | |
public void HandleMessage(String message) | |
{ | |
handleFromJs(message); | |
} | |
public void HandleSyncMessage(String message) | |
{ | |
handleFromJs(message, false); | |
} | |
private dynamic native_; | |
public void sendToJs(String message, bool sendAsync = true) | |
{ | |
if (sendAsync) | |
{ | |
native_.PostMessageToJS(message); | |
} | |
else | |
{ | |
native_.SendSyncReply(message); | |
} | |
} | |
public void sendToJs(Dictionary<string, object> message, bool sendAsync) | |
{ | |
sendToJs(JsonConvert.SerializeObject(message), sendAsync); | |
} | |
public void sendToJs(object[] message, bool sendAsync) | |
{ | |
sendToJs(JsonConvert.SerializeObject(message), sendAsync); | |
} | |
public void sendToJs(int message, bool sendAsync) | |
{ | |
sendToJs(JsonConvert.SerializeObject(message), sendAsync); | |
} | |
public void handleFromJs(String json, bool wasAsync = true) | |
{ | |
Dictionary<string, object> response = new Dictionary<string, object>(); | |
try | |
{ | |
if (json == "GETAPI") | |
{ | |
RegisterApiMethods(typeof(XWalkExtension)); | |
sendToJs(GetApiMethodNames, wasAsync); | |
return; | |
} | |
else if (json == "GETADDINSCOUNT") | |
{ | |
if (addinsException != null) | |
{ | |
sendToJs(addinsException.Message, wasAsync); | |
} | |
else | |
{ | |
sendToJs(addinsCount, wasAsync); | |
} | |
} | |
Dictionary<string, object> message = JsonConvert.DeserializeObject<Dictionary<string, object>>(json); | |
if (message.ContainsKey("asyncCallId")) | |
{ | |
response["asyncCallId"] = message["asyncCallId"]; | |
} | |
if (message.ContainsKey("method")) | |
{ | |
object requestedApiMethod; | |
if (!message.TryGetValue("method", out requestedApiMethod)) | |
{ | |
throw new Exception("Failed to identify API method! :" + json); | |
} | |
else if (!(requestedApiMethod is string)) | |
{ | |
throw new Exception("API method was not a string! :" + json); | |
} | |
Dictionary<string, object> methodResponse = CallApiMethod((string)requestedApiMethod, message); | |
foreach (string key in methodResponse.Keys) | |
{ | |
response[key] = methodResponse[key]; | |
} | |
} | |
else | |
{ | |
throw new Exception("Unsupported API call! :" + json); | |
} | |
} | |
catch (Exception err) | |
{ | |
response["error"] = err.Message; | |
} | |
if (!response.ContainsKey("error")) | |
{ | |
response["success"] = true; | |
} | |
sendToJs(response, wasAsync); | |
} | |
private static Type expectedReturnType | |
{ | |
get | |
{ | |
return typeof(Dictionary<string, object>); | |
} | |
} | |
private static Dictionary<string, Delegate> apiMethods = new Dictionary<string, Delegate>(); | |
public string[] GetApiMethodNames | |
{ | |
get | |
{ | |
return apiMethods.Keys.ToArray(); | |
} | |
} | |
public Dictionary<string, object> CallApiMethod(string methodName, Dictionary<string, object> methodArgs) | |
{ | |
if (!apiMethods.ContainsKey(methodName)) | |
{ | |
throw new ArgumentException("The specified method does not exist!"); | |
} | |
return (Dictionary<string, object>)apiMethods[methodName].DynamicInvoke( | |
new object[] { | |
(object)methodArgs | |
} | |
); | |
} | |
public void RegisterApiMethods(Type t) | |
{ | |
XWalkExtensionMethod methodAttr; | |
bool anyAdded = false; | |
Type expectedReturnType = typeof(Dictionary<string, object>); ; | |
MethodInfo[] methods = t.GetMethods(BindingFlags.Public | BindingFlags.Static); | |
if (methods.Length < 1) | |
{ | |
throw new ArgumentException("Type has no methods!"); | |
} | |
foreach (MethodInfo method in methods) | |
{ | |
if (method.GetCustomAttributes(typeof(XWalkExtensionMethod), true).Any()) | |
{ | |
if (method.ReturnType != expectedReturnType) | |
{ | |
throw new ArgumentException("Methods are expected to return Dictionary<string, object>"); | |
} | |
methodAttr = method.GetCustomAttribute<XWalkExtensionMethod>(); | |
try | |
{ | |
apiMethods[methodAttr.GetMethodName()] = CreateDelegate(method); | |
} | |
catch (Exception ex) | |
{ | |
throw new Exception("Could not create delegate!", ex); | |
} | |
anyAdded = true; | |
} | |
} | |
if (!anyAdded) | |
{ | |
throw new ArgumentException("Specified type does not specify any API methods!"); | |
} | |
} | |
private static Delegate CreateDelegate(MethodInfo method) | |
{ | |
if (method == null) | |
{ | |
throw new ArgumentNullException("Cannot create delegate from null method"); | |
} | |
ParameterExpression[] parameters = method.GetParameters().Select(p => Expression.Parameter(p.ParameterType, p.Name)).ToArray(); | |
MethodCallExpression call = Expression.Call(null, method, parameters); | |
return Expression.Lambda(call, parameters).Compile(); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
namespace xwalk | |
{ | |
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)] | |
class XWalkExtensionMethod : Attribute | |
{ | |
private string _name; | |
public XWalkExtensionMethod(string name) | |
{ | |
_name = name; | |
} | |
public string GetMethodName() | |
{ | |
return _name; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
r2 invoked with: