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

Commit 697b2af

Browse files
committed
[Windows] Add binary data transfer from .net extensions.
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
1 parent d3bbb71 commit 697b2af

File tree

9 files changed

+190
-0
lines changed

9 files changed

+190
-0
lines changed

dotnet/xwalk_dotnet_bridge.cc

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ xwalk::extensions::XWalkDotNetBridge* g_bridge = nullptr;
2222
XW_Extension g_xw_extension = 0;
2323
const XW_CoreInterface* g_core = nullptr;
2424
const XW_MessagingInterface* g_messaging = nullptr;
25+
const XW_MessagingInterface2* g_messaging2 = nullptr;
2526
const XW_Internal_SyncMessagingInterface* g_sync_messaging = nullptr;
2627
const XW_Internal_EntryPointsInterface* g_entry_points = nullptr;
2728
const XW_Internal_RuntimeInterface* g_runtime = nullptr;
@@ -53,6 +54,14 @@ bool InitializeInterfaces(XW_GetInterface get_interface) {
5354
return false;
5455
}
5556

57+
g_messaging2 = reinterpret_cast<const XW_MessagingInterface2*>(
58+
get_interface(XW_MESSAGING_INTERFACE_2));
59+
if (!g_messaging2) {
60+
std::cerr <<
61+
"Can't initialize extension: error getting binary Messaging interface.\n";
62+
return false;
63+
}
64+
5665
g_sync_messaging =
5766
reinterpret_cast<const XW_Internal_SyncMessagingInterface*>(
5867
get_interface(XW_INTERNAL_SYNC_MESSAGING_INTERFACE));
@@ -136,6 +145,13 @@ public ref class Bridge : public Object {
136145
void setNativeInstance(XW_Instance instance) {
137146
instance_ = instance;
138147
}
148+
void PostBinaryMessageToJS(array<unsigned char>^ message, size_t size) {
149+
pin_ptr<unsigned char> message_pin = &message[0];
150+
const unsigned char* message_ptr = message_pin;
151+
const char* message_to_js = (const char*)(message_ptr);
152+
153+
bridge_->PostBinaryMessageToInstance(instance_, message_to_js, size);
154+
}
139155
void PostMessageToJS(String^ message) {
140156
std::string message_to_js;
141157
MarshalString(message, &message_to_js);
@@ -409,6 +425,12 @@ void XWalkDotNetBridge::HandleSyncMessage(XW_Instance instance,
409425
}
410426

411427
#undef PostMessage
428+
void XWalkDotNetBridge::PostBinaryMessageToInstance(XW_Instance instance,
429+
const char* message,
430+
const size_t size) {
431+
g_messaging2->PostBinaryMessage(instance, message, size);
432+
}
433+
412434
void XWalkDotNetBridge::PostMessageToInstance(XW_Instance instance,
413435
const std::string& message) {
414436
g_messaging->PostMessage(instance, message.c_str());

dotnet/xwalk_dotnet_bridge.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
#include "xwalk/extensions/public/XW_Extension.h"
1010
#include "xwalk/extensions/public/XW_Extension_EntryPoints.h"
11+
#include "xwalk/extensions/public/XW_Extension_Message_2.h"
1112
#include "xwalk/extensions/public/XW_Extension_Permissions.h"
1213
#include "xwalk/extensions/public/XW_Extension_Runtime.h"
1314
#include "xwalk/extensions/public/XW_Extension_SyncMessage.h"
@@ -32,6 +33,7 @@ class XWalkDotNetBridge {
3233

3334
bool Initialize();
3435
XWalkExtensionDotNetInstance CreateInstance(XW_Instance native_instance);
36+
void PostBinaryMessageToInstance(XW_Instance instance, const char* message, const size_t size);
3537
void PostMessageToInstance(XW_Instance instance, const std::string& message);
3638
void SetSyncReply(XW_Instance instance, const std::string& message);
3739

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<html>
2+
<head>
3+
<title></title>
4+
</head>
5+
<body>
6+
<script>
7+
try {
8+
binaryTest.binaryEcho("Pass", function(buf) {
9+
var msg = String.fromCharCode.apply(null, new Uint16Array(buf));
10+
document.title = msg;
11+
});
12+
} catch(e) {
13+
console.log(e);
14+
document.title = "Fail";
15+
}
16+
</script>
17+
</body>
18+
</html>

extensions/test/win/BUILD.gn

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,10 +174,23 @@ msbuild("dotnet_echo_extension2") {
174174
]
175175
}
176176

177+
msbuild("dotnet_binary_extension") {
178+
testonly = true
179+
visibility = [ ":*" ]
180+
output_dir = "$_out_dir_prefix/binary_extension"
181+
output_name = "binary_extension"
182+
project_path = "binary_extension/binary_extension.csproj"
183+
sources = [
184+
"binary_extension/XWalkExtension.cs",
185+
"binary_extension/XWalkExtensionInstance.cs",
186+
]
187+
}
188+
177189
group("dotnet_extensions") {
178190
visibility = [ ":*" ]
179191
testonly = true
180192
public_deps = [
193+
":dotnet_binary_extension",
181194
":dotnet_echo_extension",
182195
":dotnet_echo_extension1",
183196
":dotnet_echo_extension2",
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// Copyright (c) 2013 Intel Corporation. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
using System;
6+
7+
namespace xwalk
8+
{
9+
public class XWalkExtension
10+
{
11+
public XWalkExtension() {
12+
}
13+
14+
public String ExtensionName() {
15+
return "binaryTest";
16+
}
17+
18+
public String ExtensionAPI() {
19+
return
20+
@"var binaryTestListener = null;
21+
extension.setMessageListener(function(msg) {
22+
if (binaryTestListener instanceof Function) {
23+
binaryTestListener(msg);
24+
};
25+
});
26+
exports.binaryEcho = function(msg, callback) {
27+
binaryTestListener = callback;
28+
extension.postMessage(msg);
29+
};
30+
}
31+
}
32+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// Copyright (c) 2013 Intel Corporation. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
using System;
6+
7+
namespace xwalk
8+
{
9+
public class XWalkExtensionInstance
10+
{
11+
public XWalkExtensionInstance(dynamic native) {
12+
native_ = native;
13+
}
14+
15+
public void HandleMessage(String message) {
16+
byte[] bytes = System.Text.Encoding.Unicode.GetBytes(message);
17+
native_.PostBinaryMessageToJS(bytes, (ulong)bytes.Length);
18+
}
19+
public void HandleSyncMessage(String message) {
20+
native_.SendSyncReply(message);
21+
}
22+
private dynamic native_;
23+
}
24+
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
3+
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
4+
<PropertyGroup>
5+
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
6+
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
7+
<ProjectGuid>{D70B6453-8366-40F2-9504-EF9BD45C5843}</ProjectGuid>
8+
<OutputType>Library</OutputType>
9+
<AppDesignerFolder>Properties</AppDesignerFolder>
10+
<RootNamespace>binary_extension</RootNamespace>
11+
<AssemblyName>binary_extension</AssemblyName>
12+
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
13+
<FileAlignment>512</FileAlignment>
14+
</PropertyGroup>
15+
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
16+
<DebugSymbols>true</DebugSymbols>
17+
<DebugType>full</DebugType>
18+
<Optimize>false</Optimize>
19+
<OutputPath>bin\Debug\</OutputPath>
20+
<DefineConstants>DEBUG;TRACE</DefineConstants>
21+
<ErrorReport>prompt</ErrorReport>
22+
<WarningLevel>4</WarningLevel>
23+
</PropertyGroup>
24+
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
25+
<DebugType>pdbonly</DebugType>
26+
<Optimize>true</Optimize>
27+
<OutputPath>bin\Release\</OutputPath>
28+
<DefineConstants>TRACE</DefineConstants>
29+
<ErrorReport>prompt</ErrorReport>
30+
<WarningLevel>4</WarningLevel>
31+
</PropertyGroup>
32+
<ItemGroup>
33+
<Reference Include="System" />
34+
<Reference Include="System.Core" />
35+
<Reference Include="System.Data.DataSetExtensions" />
36+
<Reference Include="Microsoft.CSharp" />
37+
<Reference Include="System.Data" />
38+
<Reference Include="System.Xml" />
39+
</ItemGroup>
40+
<ItemGroup>
41+
<Compile Include="XWalkExtension.cs" />
42+
<Compile Include="XWalkExtensionInstance.cs" />
43+
</ItemGroup>
44+
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
45+
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
46+
Other similar extension points exist, see Microsoft.Common.targets.
47+
<Target Name="BeforeBuild">
48+
</Target>
49+
<Target Name="AfterBuild">
50+
</Target>
51+
-->
52+
</Project>

extensions/test/win/xwalk_dotnet_extension_unittest.cc

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,4 +132,12 @@ TEST(XWalkDotNetExtensionTest, InvalidExtensions) {
132132
EXPECT_TRUE(invalid_extension_12->Initialize());
133133
instance = invalid_extension_12->CreateExternalInstance();
134134
EXPECT_FALSE(instance->GetInstanceData());
135+
136+
test_path = GetDotNetExtensionTestPath(
137+
FILE_PATH_LITERAL("binary_extension/binary_extension_bridge.dll"));
138+
TestExtension* valid_extension = new TestExtension(test_path);
139+
EXPECT_TRUE(base::PathExists(test_path));
140+
EXPECT_TRUE(valid_extension->Initialize());
141+
XWalkExternalInstance* instance = valid_extension->CreateExternalInstance();
142+
EXPECT_TRUE(instance->GetInstanceData());
135143
}

extensions/test/win/xwalk_dotnet_extensions_browsertest.cc

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,15 @@ class DotNetMultipleExtensionTest : public XWalkExtensionsTestBase {
3434
}
3535
};
3636

37+
class DotNetBinaryTest : public XWalkExtensionsTestBase {
38+
public:
39+
void SetUp() override {
40+
XWalkExtensionService::SetExternalExtensionsPathForTesting(
41+
GetDotNetExtensionTestPath(FILE_PATH_LITERAL("binary_extension")));
42+
XWalkExtensionsTestBase::SetUp();
43+
}
44+
};
45+
3746
IN_PROC_BROWSER_TEST_F(DotNetEchoTest, DotNetExtension) {
3847
Runtime* runtime = CreateRuntime();
3948
GURL url = GetExtensionsTestURL(base::FilePath(),
@@ -65,3 +74,13 @@ IN_PROC_BROWSER_TEST_F(DotNetMultipleExtensionTest, DotnetExtensionMultiple) {
6574
xwalk_test_utils::NavigateToURL(runtime, url);
6675
EXPECT_EQ(kPassString, title_watcher.WaitAndGetTitle());
6776
}
77+
78+
IN_PROC_BROWSER_TEST_F(DotNetBinaryTest, DotNetExtension) {
79+
Runtime* runtime = CreateRuntime();
80+
GURL url = GetExtensionsTestURL(base::FilePath(),
81+
base::FilePath().AppendASCII("binaryTest.html"));
82+
content::TitleWatcher title_watcher(runtime->web_contents(), kPassString);
83+
title_watcher.AlsoWaitForTitle(kFailString);
84+
xwalk_test_utils::NavigateToURL(runtime, url);
85+
EXPECT_EQ(kPassString, title_watcher.WaitAndGetTitle());
86+
}

0 commit comments

Comments
 (0)