Commit c9d938c5 authored by Ben Smith's avatar Ben Smith

[NaCl SDK] Add filesystem passing example.

BUG=none
R=sbc@chromium.org

Review URL: https://codereview.chromium.org/690403002

Cr-Commit-Position: refs/heads/master@{#302480}
parent 4c65a7f9
......@@ -147,10 +147,13 @@ def GenerateManifest(srcroot, dstroot, desc):
srcpath = os.path.join(SDK_RESOURCE_DIR, 'manifest.json.template')
dstpath = os.path.join(outdir, 'manifest.json')
permissions = desc.get('PERMISSIONS', [])
socket_permissions = desc.get('SOCKET_PERMISSIONS', [])
combined_permissions = list(permissions)
socket_permissions = desc.get('SOCKET_PERMISSIONS', [])
if socket_permissions:
combined_permissions.append({'socket': socket_permissions})
filesystem_permissions = desc.get('FILESYSTEM_PERMISSIONS', [])
if filesystem_permissions:
combined_permissions.append({'fileSystem': filesystem_permissions})
pretty_permissions = json.dumps(combined_permissions,
sort_keys=True, indent=4)
replace = {
......
......@@ -66,6 +66,7 @@ DSC_FORMAT = {
'EXPERIMENTAL': (bool, [True, False], False),
'PERMISSIONS': (list, '', False),
'SOCKET_PERMISSIONS': (list, '', False),
'FILESYSTEM_PERMISSIONS': (list, '', False),
'MULTI_PLATFORM': (bool, [True, False], False),
'MIN_CHROME_VERSION': (str, '', False),
}
......
......@@ -43,6 +43,7 @@ examples/index.js
examples/Makefile
examples/tutorial/debugging/*
examples/tutorial/dlopen/*
examples/tutorial/filesystem_passing/*
examples/tutorial/load_progress/*
examples/tutorial/multi_platform/*
[win]examples/tutorial/make.bat
......
{
'TOOLS': ['newlib', 'glibc', 'bionic', 'pnacl'],
'TARGETS': [
{
'NAME' : 'filesystem_passing',
'TYPE' : 'main',
'SOURCES' : ['filesystem_passing.cc'],
'LIBS' : ['ppapi_cpp', 'ppapi', 'pthread']
}
],
'DATA': [
'example.js',
],
'DEST': 'examples/tutorial',
'NAME': 'filesystem_passing',
'TITLE': 'Filesystem Passing',
'GROUP': 'Tutorial',
'FILESYSTEM_PERMISSIONS': [
'write',
'directory'
]
}
// Copyright (c) 2014 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.
function attachListeners() {
document.getElementById('choosedir').addEventListener('click', function(e) {
chrome.fileSystem.chooseEntry({type: 'openDirectory'}, function(entry) {
if (!entry) {
// The user cancelled the dialog.
return;
}
// Send the filesystem and the directory path to the NaCl module.
common.naclModule.postMessage({
filesystem: entry.filesystem,
fullPath: entry.fullPath
});
});
}, false);
}
// Called by the common.js module.
function moduleDidLoad() {
// The module is not hidden by default so we can easily see if the plugin
// failed to load.
common.hideModule();
// Make sure this example is running as an App. If not, display a warning.
if (!chrome.fileSystem) {
common.updateStatus('Error: must be run as an App.');
return;
}
}
// Called by the common.js module.
function handleMessage(message_event) {
common.logMessage(message_event.data);
}
// Copyright (c) 2014 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 <string>
#include "ppapi/c/pp_errors.h"
#include "ppapi/c/ppb_file_io.h"
#include "ppapi/cpp/file_io.h"
#include "ppapi/cpp/file_ref.h"
#include "ppapi/cpp/file_system.h"
#include "ppapi/cpp/instance.h"
#include "ppapi/cpp/module.h"
#include "ppapi/cpp/var.h"
#include "ppapi/cpp/var_dictionary.h"
#include "ppapi/utility/completion_callback_factory.h"
#include "ppapi/utility/threading/simple_thread.h"
#ifdef WIN32
#undef PostMessage
// Allow 'this' in initializer list
#pragma warning(disable : 4355)
#endif
class Instance : public pp::Instance {
public:
explicit Instance(PP_Instance instance)
: pp::Instance(instance),
callback_factory_(this),
thread_(this) {}
private:
virtual bool Init(uint32_t /*argc*/,
const char* /*argn*/ [],
const char* /*argv*/ []) {
thread_.Start();
return true;
}
virtual void HandleMessage(const pp::Var& var_message) {
// Got a message from JavaScript. We're assuming it is a dictionary with
// two elements:
// {
// filesystem: <A Filesystem var>,
// fullPath: <A string>
// }
pp::VarDictionary var_dict(var_message);
pp::Resource filesystem_resource = var_dict.Get("filesystem").AsResource();
pp::FileSystem filesystem(filesystem_resource);
std::string full_path = var_dict.Get("fullPath").AsString();
std::string save_path = full_path + "/hello_from_nacl.txt";
std::string contents = "Hello, from Native Client!\n";
thread_.message_loop().PostWork(callback_factory_.NewCallback(
&Instance::WriteFile, filesystem, save_path, contents));
}
void WriteFile(int32_t /* result */,
const pp::FileSystem& filesystem,
const std::string& path,
const std::string& contents) {
pp::FileRef ref(filesystem, path.c_str());
pp::FileIO file(this);
int32_t open_result =
file.Open(ref, PP_FILEOPENFLAG_WRITE | PP_FILEOPENFLAG_CREATE |
PP_FILEOPENFLAG_TRUNCATE,
pp::BlockUntilComplete());
if (open_result != PP_OK) {
PostMessage("Failed to open file.");
return;
}
int64_t offset = 0;
int32_t bytes_written = 0;
do {
bytes_written = file.Write(offset, contents.data() + offset,
contents.length(), pp::BlockUntilComplete());
if (bytes_written > 0) {
offset += bytes_written;
} else {
PostMessage("Failed to write file.");
return;
}
} while (bytes_written < static_cast<int64_t>(contents.length()));
// All bytes have been written, flush the write buffer to complete
int32_t flush_result = file.Flush(pp::BlockUntilComplete());
if (flush_result != PP_OK) {
PostMessage("Failed to flush file.");
return;
}
PostMessage(std::string("Wrote file ") + path + ".");
}
private:
pp::CompletionCallbackFactory<Instance> callback_factory_;
pp::SimpleThread thread_;
};
class Module : public pp::Module {
public:
Module() : pp::Module() {}
virtual ~Module() {}
virtual pp::Instance* CreateInstance(PP_Instance instance) {
return new Instance(instance);
}
};
namespace pp {
Module* CreateModule() { return new ::Module(); }
} // namespace pp
<!DOCTYPE html>
<html>
<!--
Copyright (c) 2014 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>
This example shows how to pass a Chrome FileSystem to the Native Client
module. The standard Pepper FileSystem (see examples/api/file_io) only
allows you to write to a sandboxed filesystem, but the Chrome FileSystem
allows you to write directly to a directory on the user's filesystem.
</p>
<p>The Chrome FileSystem is only supported for Chrome Apps.</p>
<p>
Click the button below and choose a directory. A new FileSystem will be
created which contains that directory. It will then be passed to the Native
Client module, where it will be used to write a file in that directory
called hello_from_nacl.txt.
</p>
<div>
<input type="button" id="choosedir" value="Choose Directory">
<pre id="log"></pre>
<div id="listener"></div>
</body>
</html>
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment