forked from chromium/chromium
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
ppapi: PPB_VpnProvider: Add a simple NaCl SDK example.
Co-Authored-By: Valentin Ilie <valentin.ilie@intel.com> BUG=506490 Review-Url: https://codereview.chromium.org/1731273002 Cr-Commit-Position: refs/heads/master@{#406516}
- Loading branch information
1 parent
98fea99
commit bb921df
Showing
8 changed files
with
531 additions
and
0 deletions.
There are no files selected for viewing
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
The VpnProvider example demonstrates how to use the VpnProvider API. | ||
|
||
This NaCl SDK example can only be used as an extension on Chrome OS. | ||
|
||
== Compile == | ||
Run "make" from this folder, then open up chrome://extensions | ||
in the browser select "Pack extension...", browse to examples/api/vpn_provider, | ||
click on "Open", then on "Pack extension" and "OK". Copy the .crx to the | ||
Chromebook. | ||
|
||
== Install == | ||
To "sideload" an app or extension under Chrome OS, open up chrome://extensions | ||
in the browser on the Chromebook, then open the file manager with Alt-Shift-M, | ||
then drag the .crx file onto the extensions page. | ||
|
||
== Test == | ||
After loading the extension to a Chromebook, open the 'VPN Provider' app. | ||
Wait for the connection to be created. From the network configuration menu | ||
select the 'Mock configuration' entry. | ||
|
||
Observe the connection setup flow in the "VPN Provider" app. |
25 changes: 25 additions & 0 deletions
25
native_client_sdk/src/examples/api/vpn_provider/example.dsc
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
{ | ||
'TARGETS': [ | ||
{ | ||
'NAME' : 'vpn_provider', | ||
'TYPE' : 'main', | ||
'SOURCES' : [ | ||
'vpn_provider.cc', | ||
'vpn_provider_helper.cc', | ||
'vpn_provider_helper.h' | ||
], | ||
'LIBS': ['ppapi_cpp', 'ppapi'] | ||
} | ||
], | ||
'DATA': [ | ||
'example.js', | ||
'README', | ||
], | ||
'DEST': 'examples/api', | ||
'NAME': 'vpn_provider', | ||
'TITLE': 'VPN Provider', | ||
'GROUP': 'API', | ||
'PERMISSIONS': [ | ||
'vpnProvider' | ||
] | ||
} |
134 changes: 134 additions & 0 deletions
134
native_client_sdk/src/examples/api/vpn_provider/example.js
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,134 @@ | ||
// Copyright 2016 The Chromium Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
// VPN Configuration identification. | ||
var configName = 'Mock configuration'; | ||
var configId; | ||
|
||
// Example configuration. | ||
var vpnParams = { | ||
'address': '127.0.0.1/32', | ||
'mtu': '1000', | ||
'exclusionList': ['127.0.0.1/32'], | ||
'inclusionList': ['0.0.0.0/0'], | ||
'dnsServers': ['8.8.8.8'], | ||
'reconnect': 'true' | ||
}; | ||
|
||
// Simple log to HTML | ||
function wlog(message) { | ||
var logEl = document.getElementById('log'); | ||
logEl.innerHTML += message + '<br />'; // Append to log. | ||
logEl.scrollTop = logEl.scrollHeight; // Scroll log to bottom. | ||
} | ||
|
||
// Create a VPN configuration using the createConfig method. | ||
// A VPN configuration is a persistent entry shown to the user in a native | ||
// Chrome OS UI. The user can select a VPN configuration from a list and | ||
// connect to it or disconnect from it. | ||
function create() { | ||
chrome.vpnProvider.createConfig(configName, function(id) { | ||
configId = id; | ||
wlog('JS: Created configuration with name=\'' + configName + '\'' + | ||
' and id=\'' + configId + '\''); | ||
}); | ||
} | ||
|
||
// Bind connection to NaCl. | ||
function bind() { | ||
common.naclModule.postMessage({cmd: 'bind', name: configName, id: configId}); | ||
} | ||
|
||
function onSetParameters() { | ||
chrome.vpnProvider.setParameters(vpnParams, function() { | ||
wlog('JS: setParameters set!'); | ||
|
||
// Bind connection to NaCl. | ||
bind(); | ||
}); | ||
} | ||
|
||
function onBindSuccess() { | ||
// Notify the connection state as 'connected'. | ||
chrome.vpnProvider.notifyConnectionStateChanged('connected', function() { | ||
wlog('JS: notifyConnectionStateChanged connected!'); | ||
}); | ||
} | ||
|
||
// VpnProviders handlers. | ||
function onPlatformMessageListener(id, message, error) { | ||
wlog('JS: onPlatformMessage: id=\'' + id + '\' message=\'' + message + | ||
'\' error=\'' + error + '\''); | ||
|
||
if (message == 'connected') { | ||
wlog('JS: onPlatformMessage connected!'); | ||
|
||
// Notify NaCl module to connect to the VPN tunnel. | ||
common.naclModule.postMessage({cmd: 'connected'}); | ||
|
||
} else if (message == 'disconnected') { | ||
wlog('JS: onPlatformMessage disconnected!'); | ||
|
||
// Notify NaCl module to disconnect from the VPN tunnel. | ||
common.naclModule.postMessage({cmd: 'disconnected'}); | ||
} | ||
} | ||
|
||
// This function is called by common.js when a message is received from the | ||
// NaCl module. | ||
function handleMessage(message) { | ||
if (typeof message.data === 'string') { | ||
wlog(message.data); | ||
} else if (message.data['cmd'] == 'setParameters') { | ||
onSetParameters(); | ||
} else if (message.data['cmd'] == 'bindSuccess') { | ||
onBindSuccess(); | ||
} | ||
} | ||
|
||
// setupHandlers VpnProviders handlers. | ||
function setupHandlers() { | ||
// Add listeners to the events onPlatformMessage, onPacketReceived and | ||
// onConfigRemoved. | ||
chrome.vpnProvider.onPlatformMessage.addListener(onPlatformMessageListener); | ||
|
||
chrome.vpnProvider.onPacketReceived.addListener(function(data) { | ||
wlog('JS: onPacketReceived'); | ||
console.log('Unexpected event:vpnProvider.onPacketReceived ' + | ||
'called from JavaScript.'); | ||
}); | ||
|
||
chrome.vpnProvider.onConfigRemoved.addListener(function(id) { | ||
wlog('JS: onConfigRemoved: id=\'' + id + '\''); | ||
}); | ||
|
||
chrome.vpnProvider.onConfigCreated.addListener(function(id, name, data) { | ||
wlog('JS: onConfigCreated: id=\'' + id + '\' name=\'' + name + '\'' + | ||
'data=' + JSON.stringify(data)); | ||
}); | ||
|
||
chrome.vpnProvider.onUIEvent.addListener(function(event, id) { | ||
wlog('JS: onUIEvent: event=\'' + event + '\' id=\'' + id + '\''); | ||
}); | ||
} | ||
|
||
// This function is called by common.js when the NaCl module is | ||
// loaded. | ||
function moduleDidLoad() { | ||
// Once we load, hide the plugin. In this example, we don't display anything | ||
// in the plugin, so it is fine to hide it. | ||
common.hideModule(); | ||
|
||
if (chrome.vpnProvider === undefined) { | ||
wlog('JS: moduleDidLoad: chrome.vpnProvider undefined.'); | ||
console.log('JS: moduleDidLoad: chrome.vpnProvider undefined.'); | ||
return; | ||
} | ||
|
||
// Setup VpnProvider handlers. | ||
setupHandlers(); | ||
|
||
// All done, create the connection entry in the VPN UI. | ||
create(); | ||
} |
33 changes: 33 additions & 0 deletions
33
native_client_sdk/src/examples/api/vpn_provider/index.html
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
<!DOCTYPE html> | ||
<html> | ||
<!-- | ||
Copyright 2016 The Chromium Authors. All rights reserved. | ||
Use of this source code is governed by a BSD-style license that can be | ||
found in the LICENSE file. | ||
--> | ||
<head> | ||
<meta http-equiv="Pragma" content="no-cache"> | ||
<meta http-equiv="Expires" content="-1"> | ||
<title>{{title}}</title> | ||
<script type="text/javascript" src="common.js"></script> | ||
<script type="text/javascript" src="example.js"></script> | ||
</head> | ||
|
||
<body {{attrs}}> | ||
<h1>{{title}}</h1> | ||
<h2>Status: <code id="statusField">NO-STATUS</code></h2> | ||
<p>The VpnProvider example demonstrates how to use the VpnProvider API.<br/> | ||
<i>This NaCl SDK example can only be used as an extension on Chrome OS.</i> | ||
<br/>See the README file for detailed information on build and deploy. | ||
</p> | ||
<h3>Test</h3> | ||
<p>After loading the extension to a Chromebook, open the 'VPN Provider' app. | ||
<br/>Wait for the connection to be created.<br/> From the network | ||
configuration menu select the 'Mock configuration' entry. <br/> | ||
Observe the connection setup flow below. | ||
|
||
</p> | ||
<div id="listener"></div> | ||
<div id="log" style="height: 400px; overflow-y: scroll;"></div> | ||
</body> | ||
</html> |
137 changes: 137 additions & 0 deletions
137
native_client_sdk/src/examples/api/vpn_provider/vpn_provider.cc
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,137 @@ | ||
// Copyright 2016 The Chromium Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
#include <queue> | ||
#include <sstream> | ||
#include <string> | ||
|
||
#include "ppapi/cpp/instance.h" | ||
#include "ppapi/cpp/module.h" | ||
#include "ppapi/cpp/var.h" | ||
#include "ppapi/cpp/var_dictionary.h" | ||
|
||
#include "vpn_provider_helper.h" | ||
|
||
class VpnProviderInstance : public pp::Instance { | ||
public: | ||
explicit VpnProviderInstance(PP_Instance instance) | ||
: pp::Instance(instance), vpn_provider_helper_(this) { | ||
vpn_provider_helper_.Init(); | ||
} | ||
|
||
virtual ~VpnProviderInstance() {} | ||
|
||
// Handles messages from Javascript | ||
virtual void HandleMessage(const pp::Var& message) { | ||
// Expecting only dictionary messages from JS. | ||
if (!message.is_dictionary()) { | ||
PostMessage( | ||
"NaCl: VpnProviderInstance::HandleMessage: " | ||
"Unexpected message. Not a dictionary."); | ||
return; | ||
} | ||
|
||
// Message type defined by 'cmd' key. | ||
pp::VarDictionary dict(message); | ||
|
||
std::string command; | ||
if (!GetStringFromMessage(dict, "cmd", &command)) { | ||
return; | ||
} | ||
if (command == "bind") { | ||
std::string name, id; | ||
if (!GetStringFromMessage(dict, "name", &name) || | ||
!GetStringFromMessage(dict, "id", &id)) { | ||
return; | ||
} | ||
PostMessage( | ||
"NaCl: VpnProviderInstance::HandleMessage: " | ||
"Bind request."); | ||
vpn_provider_helper_.Bind(name, id); | ||
return; | ||
} | ||
|
||
if (command == "connected") { | ||
PostMessage( | ||
"NaCl: VpnProviderInstance::HandleMessage: " | ||
"Connect request."); | ||
|
||
/* This is the place where the developer would establing the VPN | ||
* connection. The response would usually contain configuration details | ||
* for the tunnel obtained from the VPN implementation. | ||
* | ||
* Currently just signaling that is was executed succesfuly. | ||
*/ | ||
|
||
pp::VarDictionary dict; | ||
dict.Set("cmd", "setParameters"); | ||
PostMessage(dict); | ||
return; | ||
} | ||
|
||
if (command == "disconnected") { | ||
PostMessage( | ||
"NaCl: VpnProviderInstance::HandleMessage: " | ||
"Disconnect request."); | ||
|
||
/* This is the place where the developer would disconnect from the VPN | ||
* connection. | ||
*/ | ||
|
||
return; | ||
} | ||
|
||
PostMessage( | ||
"NaCl: VpnProviderInstance::HandleMessage: " | ||
"Unexpected command."); | ||
} | ||
|
||
private: | ||
// Helper function for HandleMessage | ||
bool GetStringFromMessage(const pp::VarDictionary& dict, | ||
const char* key, | ||
std::string* value) { | ||
if (!value) | ||
return false; | ||
|
||
pp::Var val = dict.Get(key); | ||
if (val.is_undefined()) { | ||
std::stringstream ss; | ||
ss << "NaCl: VpnProviderInstance::HandleMessage: Malformed message. No '" | ||
<< key << "' key."; | ||
PostMessage(ss.str()); | ||
return false; | ||
} | ||
if (!val.is_string()) { | ||
std::stringstream ss; | ||
ss << "NaCl: VpnProviderInstance::HandleMessage: Malformed message. "; | ||
ss << "Type for key '" << key << "' is not string"; | ||
PostMessage(ss.str()); | ||
return false; | ||
} | ||
|
||
*value = val.AsString(); | ||
return true; | ||
} | ||
|
||
VpnProviderHelper vpn_provider_helper_; | ||
}; | ||
|
||
class VpnProviderModule : public pp::Module { | ||
public: | ||
VpnProviderModule() : pp::Module() {} | ||
virtual ~VpnProviderModule() {} | ||
|
||
virtual pp::Instance* CreateInstance(PP_Instance instance) { | ||
return new VpnProviderInstance(instance); | ||
} | ||
}; | ||
|
||
namespace pp { | ||
|
||
Module* CreateModule() { | ||
return new VpnProviderModule(); | ||
} | ||
|
||
} // namespace pp |
Oops, something went wrong.