Skip to content
This repository has been archived by the owner on Apr 3, 2020. It is now read-only.

Commit

Permalink
[Windows] Add binary data transfer from .net extensions.
Browse files Browse the repository at this point in the history
Exposes PostBinaryMessageToJS(byte[] data, ulong size) to the .net extension bridge.
 - Uses XW_MessagingInterface2 to return an ArrayBuffer to the Javascript client
 - Improves data transfer speed for large amounts of raw data, as translating from a string is slow in Javascript.

BUG=XWALK-4615
  • Loading branch information
zcr01 committed Dec 13, 2016
1 parent d3bbb71 commit 697b2af
Show file tree
Hide file tree
Showing 9 changed files with 190 additions and 0 deletions.
22 changes: 22 additions & 0 deletions dotnet/xwalk_dotnet_bridge.cc
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ xwalk::extensions::XWalkDotNetBridge* g_bridge = nullptr;
XW_Extension g_xw_extension = 0;
const XW_CoreInterface* g_core = nullptr;
const XW_MessagingInterface* g_messaging = nullptr;
const XW_MessagingInterface2* g_messaging2 = nullptr;
const XW_Internal_SyncMessagingInterface* g_sync_messaging = nullptr;
const XW_Internal_EntryPointsInterface* g_entry_points = nullptr;
const XW_Internal_RuntimeInterface* g_runtime = nullptr;
Expand Down Expand Up @@ -53,6 +54,14 @@ bool InitializeInterfaces(XW_GetInterface get_interface) {
return false;
}

g_messaging2 = reinterpret_cast<const XW_MessagingInterface2*>(
get_interface(XW_MESSAGING_INTERFACE_2));
if (!g_messaging2) {
std::cerr <<
"Can't initialize extension: error getting binary Messaging interface.\n";
return false;
}

g_sync_messaging =
reinterpret_cast<const XW_Internal_SyncMessagingInterface*>(
get_interface(XW_INTERNAL_SYNC_MESSAGING_INTERFACE));
Expand Down Expand Up @@ -136,6 +145,13 @@ public ref class Bridge : public Object {
void setNativeInstance(XW_Instance instance) {
instance_ = instance;
}
void PostBinaryMessageToJS(array<unsigned char>^ message, size_t size) {
pin_ptr<unsigned char> message_pin = &message[0];
const unsigned char* message_ptr = message_pin;
const char* message_to_js = (const char*)(message_ptr);

bridge_->PostBinaryMessageToInstance(instance_, message_to_js, size);
}
void PostMessageToJS(String^ message) {
std::string message_to_js;
MarshalString(message, &message_to_js);
Expand Down Expand Up @@ -409,6 +425,12 @@ void XWalkDotNetBridge::HandleSyncMessage(XW_Instance instance,
}

#undef PostMessage
void XWalkDotNetBridge::PostBinaryMessageToInstance(XW_Instance instance,
const char* message,
const size_t size) {
g_messaging2->PostBinaryMessage(instance, message, size);
}

void XWalkDotNetBridge::PostMessageToInstance(XW_Instance instance,
const std::string& message) {
g_messaging->PostMessage(instance, message.c_str());
Expand Down
2 changes: 2 additions & 0 deletions dotnet/xwalk_dotnet_bridge.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

#include "xwalk/extensions/public/XW_Extension.h"
#include "xwalk/extensions/public/XW_Extension_EntryPoints.h"
#include "xwalk/extensions/public/XW_Extension_Message_2.h"
#include "xwalk/extensions/public/XW_Extension_Permissions.h"
#include "xwalk/extensions/public/XW_Extension_Runtime.h"
#include "xwalk/extensions/public/XW_Extension_SyncMessage.h"
Expand All @@ -32,6 +33,7 @@ class XWalkDotNetBridge {

bool Initialize();
XWalkExtensionDotNetInstance CreateInstance(XW_Instance native_instance);
void PostBinaryMessageToInstance(XW_Instance instance, const char* message, const size_t size);
void PostMessageToInstance(XW_Instance instance, const std::string& message);
void SetSyncReply(XW_Instance instance, const std::string& message);

Expand Down
18 changes: 18 additions & 0 deletions extensions/test/data/binaryTest.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<html>
<head>
<title></title>
</head>
<body>
<script>
try {
binaryTest.binaryEcho("Pass", function(buf) {
var msg = String.fromCharCode.apply(null, new Uint16Array(buf));
document.title = msg;
});
} catch(e) {
console.log(e);
document.title = "Fail";
}
</script>
</body>
</html>
13 changes: 13 additions & 0 deletions extensions/test/win/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -174,10 +174,23 @@ msbuild("dotnet_echo_extension2") {
]
}

msbuild("dotnet_binary_extension") {
testonly = true
visibility = [ ":*" ]
output_dir = "$_out_dir_prefix/binary_extension"
output_name = "binary_extension"
project_path = "binary_extension/binary_extension.csproj"
sources = [
"binary_extension/XWalkExtension.cs",
"binary_extension/XWalkExtensionInstance.cs",
]
}

group("dotnet_extensions") {
visibility = [ ":*" ]
testonly = true
public_deps = [
":dotnet_binary_extension",
":dotnet_echo_extension",
":dotnet_echo_extension1",
":dotnet_echo_extension2",
Expand Down
32 changes: 32 additions & 0 deletions extensions/test/win/binary_extension/XWalkExtension.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// Copyright (c) 2013 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;

namespace xwalk
{
public class XWalkExtension
{
public XWalkExtension() {
}

public String ExtensionName() {
return "binaryTest";
}

public String ExtensionAPI() {
return
@"var binaryTestListener = null;
extension.setMessageListener(function(msg) {
if (binaryTestListener instanceof Function) {
binaryTestListener(msg);
};
});
exports.binaryEcho = function(msg, callback) {
binaryTestListener = callback;
extension.postMessage(msg);
};
}
}
}
24 changes: 24 additions & 0 deletions extensions/test/win/binary_extension/XWalkExtensionInstance.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// Copyright (c) 2013 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;

namespace xwalk
{
public class XWalkExtensionInstance
{
public XWalkExtensionInstance(dynamic native) {
native_ = native;
}

public void HandleMessage(String message) {
byte[] bytes = System.Text.Encoding.Unicode.GetBytes(message);
native_.PostBinaryMessageToJS(bytes, (ulong)bytes.Length);
}
public void HandleSyncMessage(String message) {
native_.SendSyncReply(message);
}
private dynamic native_;
}
}
52 changes: 52 additions & 0 deletions extensions/test/win/binary_extension/binary_extension.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{D70B6453-8366-40F2-9504-EF9BD45C5843}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>binary_extension</RootNamespace>
<AssemblyName>binary_extension</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="XWalkExtension.cs" />
<Compile Include="XWalkExtensionInstance.cs" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>
8 changes: 8 additions & 0 deletions extensions/test/win/xwalk_dotnet_extension_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -132,4 +132,12 @@ TEST(XWalkDotNetExtensionTest, InvalidExtensions) {
EXPECT_TRUE(invalid_extension_12->Initialize());
instance = invalid_extension_12->CreateExternalInstance();
EXPECT_FALSE(instance->GetInstanceData());

test_path = GetDotNetExtensionTestPath(
FILE_PATH_LITERAL("binary_extension/binary_extension_bridge.dll"));
TestExtension* valid_extension = new TestExtension(test_path);
EXPECT_TRUE(base::PathExists(test_path));
EXPECT_TRUE(valid_extension->Initialize());
XWalkExternalInstance* instance = valid_extension->CreateExternalInstance();
EXPECT_TRUE(instance->GetInstanceData());
}
19 changes: 19 additions & 0 deletions extensions/test/win/xwalk_dotnet_extensions_browsertest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,15 @@ class DotNetMultipleExtensionTest : public XWalkExtensionsTestBase {
}
};

class DotNetBinaryTest : public XWalkExtensionsTestBase {
public:
void SetUp() override {
XWalkExtensionService::SetExternalExtensionsPathForTesting(
GetDotNetExtensionTestPath(FILE_PATH_LITERAL("binary_extension")));
XWalkExtensionsTestBase::SetUp();
}
};

IN_PROC_BROWSER_TEST_F(DotNetEchoTest, DotNetExtension) {
Runtime* runtime = CreateRuntime();
GURL url = GetExtensionsTestURL(base::FilePath(),
Expand Down Expand Up @@ -65,3 +74,13 @@ IN_PROC_BROWSER_TEST_F(DotNetMultipleExtensionTest, DotnetExtensionMultiple) {
xwalk_test_utils::NavigateToURL(runtime, url);
EXPECT_EQ(kPassString, title_watcher.WaitAndGetTitle());
}

IN_PROC_BROWSER_TEST_F(DotNetBinaryTest, DotNetExtension) {
Runtime* runtime = CreateRuntime();
GURL url = GetExtensionsTestURL(base::FilePath(),
base::FilePath().AppendASCII("binaryTest.html"));
content::TitleWatcher title_watcher(runtime->web_contents(), kPassString);
title_watcher.AlsoWaitForTitle(kFailString);
xwalk_test_utils::NavigateToURL(runtime, url);
EXPECT_EQ(kPassString, title_watcher.WaitAndGetTitle());
}

0 comments on commit 697b2af

Please sign in to comment.