| Index: ppapi/tests/extensions/packaged_app/test_packaged_app.cc
|
| diff --git a/ppapi/tests/extensions/packaged_app/test_packaged_app.cc b/ppapi/tests/extensions/packaged_app/test_packaged_app.cc
|
| index 754cc61809b0b9b750a24e1d58c55dfcb2cd8c89..d375a934090d098d32f55ec497117b03b199c4fe 100644
|
| --- a/ppapi/tests/extensions/packaged_app/test_packaged_app.cc
|
| +++ b/ppapi/tests/extensions/packaged_app/test_packaged_app.cc
|
| @@ -2,19 +2,128 @@
|
| // Use of this source code is governed by a BSD-style license that can be
|
| // found in the LICENSE file.
|
|
|
| +#include <pthread.h>
|
| +#include <unistd.h>
|
| +
|
| +#include <sstream>
|
| +#include <string>
|
| +
|
| +#include "native_client/src/untrusted/irt/irt.h"
|
| +
|
| +#include "ppapi/cpp/completion_callback.h"
|
| #include "ppapi/cpp/instance.h"
|
| #include "ppapi/cpp/module.h"
|
| #include "ppapi/cpp/var.h"
|
|
|
| namespace {
|
|
|
| +std::string g_last_error;
|
| +pp::Instance* g_instance = NULL;
|
| +
|
| +// This should be the same as FileDescriptorSet::kMaxDescriptorsPerMessage in
|
| +// ipc/file_descriptor_set_posix.h.
|
| +// TODO(yusukes): Once all the NaCl toolchains support C++11, Add
|
| +// #include "ipc/file_descriptor_set_posix.h" and remove the constant.
|
| +const size_t kMaxDescriptorsPerMessage = 7;
|
| +
|
| +// Returns true if the resource file whose name is |key| exists and its content
|
| +// matches |content|.
|
| +bool LoadManifestInternal(nacl_irt_resource_open* nacl_irt_resource_open,
|
| + const std::string& key,
|
| + const std::string& content) {
|
| + int desc;
|
| + int error;
|
| + error = nacl_irt_resource_open->open_resource(key.c_str(), &desc);
|
| + if (0 != error) {
|
| + g_last_error = "Can't open file " + key;
|
| + return false;
|
| + }
|
| +
|
| + std::string str;
|
| +
|
| + char buffer[4096];
|
| + int len;
|
| + while ((len = read(desc, buffer, sizeof(buffer) - 1)) > 0) {
|
| + // Null terminate.
|
| + buffer[len] = '\0';
|
| + str += buffer;
|
| + }
|
| + if (close(desc)) {
|
| + g_last_error = "Close failed: file=" + key;
|
| + return false;
|
| + }
|
| +
|
| + if (str != content) {
|
| + g_last_error = "Wrong file content: file=" + key + ", expected=" + content +
|
| + ", actual=" + str;
|
| + return false;
|
| + }
|
| +
|
| + return true;
|
| +}
|
| +
|
| +// Tests if open_resource works in a packaged app. This test is similar to
|
| +// NaClBrowserTest*.IrtManifestFile, but unlike the NaCl test, this one tests
|
| +// the "fast path" in DownloadNexe() in ppb_nacl_private_impl.cc which opens
|
| +// resource files without using URLLoader.
|
| +void LoadManifest() {
|
| + if (pthread_detach(pthread_self())) {
|
| + g_last_error = "pthread_detach failed";
|
| + return;
|
| + }
|
| +
|
| + struct nacl_irt_resource_open nacl_irt_resource_open;
|
| + if (sizeof(nacl_irt_resource_open) !=
|
| + nacl_interface_query(NACL_IRT_RESOURCE_OPEN_v0_1,
|
| + &nacl_irt_resource_open,
|
| + sizeof(nacl_irt_resource_open))) {
|
| + g_last_error = "NACL_IRT_RESOURCE_OPEN_v0_1 not found";
|
| + return;
|
| + }
|
| +
|
| + for (size_t i = 0; i <= kMaxDescriptorsPerMessage; ++i) {
|
| + std::stringstream key;
|
| + key << "test_file" << i;
|
| + std::string content = "Example contents for open_resource test" +
|
| + std::string(i % 2 ? "2" : "");
|
| + if (!LoadManifestInternal(&nacl_irt_resource_open, key.str(), content))
|
| + break;
|
| + // Open the same resource file again to make sure each file descriptor
|
| + // returned from open_resource has its own file offset.
|
| + if (!LoadManifestInternal(&nacl_irt_resource_open, key.str(), content))
|
| + break;
|
| + }
|
| +}
|
| +
|
| +void PostReply(void* user_data, int32_t status) {
|
| + if (!g_last_error.empty())
|
| + g_instance->PostMessage(g_last_error.c_str());
|
| + else
|
| + g_instance->PostMessage("Test passed");
|
| +}
|
| +
|
| +void* RunTestsOnBackgroundThread(void* thread_id) {
|
| + LoadManifest();
|
| + pp::Module::Get()->core()->CallOnMainThread(
|
| + 0, pp::CompletionCallback(&PostReply, NULL));
|
| + return NULL;
|
| +}
|
| +
|
| class MyInstance : public pp::Instance {
|
| public:
|
| - explicit MyInstance(PP_Instance instance) : pp::Instance(instance) { }
|
| + explicit MyInstance(PP_Instance instance) : pp::Instance(instance) {
|
| + g_instance = this;
|
| + }
|
| virtual ~MyInstance() { }
|
|
|
| virtual bool Init(uint32_t argc, const char* argn[], const char* argv[]) {
|
| - PostMessage("hello");
|
| + pthread_t thread;
|
| + // irt_open_resource() isn't allowed to be called on the main thread once
|
| + // Pepper starts, so the test must happen on a background thread.
|
| + if (pthread_create(&thread, NULL, &RunTestsOnBackgroundThread, NULL)) {
|
| + g_last_error = "pthread_create failed";
|
| + PostReply(NULL, 0);
|
| + }
|
| return true;
|
| }
|
| };
|
|
|