1 // Copyright (c) 2011 The Chromium Authors. 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 #include <string.h> 6 7 #include "native_client/src/include/nacl_macros.h" 8 #include "native_client/src/shared/platform/nacl_check.h" 9 10 #include "ppapi/c/pp_bool.h" 11 #include "ppapi/c/pp_errors.h" 12 #include "ppapi/c/pp_input_event.h" 13 #include "ppapi/c/ppb_instance.h" 14 #include "ppapi/c/ppb_url_loader.h" 15 #include "ppapi/c/ppp_instance.h" 16 17 #include "ppapi/native_client/tests/ppapi_test_lib/get_browser_interface.h" 18 #include "ppapi/native_client/tests/ppapi_test_lib/test_interface.h" 19 20 namespace { 21 22 23 // PostMessage is complicated in this test. We're setting up an iframe with 24 // src=foo where foo is handled by an extension as a content handler. Webkit 25 // generates the html page with the plugin embed, so we have no way to place 26 // an event handler on the plugin or body of that page that's guaranteed to 27 // execute before the plugin initializes. Instead, we're just caching the 28 // first error (if any) we encounter during load and responding to a normal 29 // test message to return the results. 30 const int kDocLoadErrorNone = 0; 31 const int kDocLoadErrorInit = -1; 32 int error_in_doc_load_line = kDocLoadErrorInit; 33 34 #define EXPECT_ON_LOAD(condition) \ 35 do { \ 36 if (!(condition)) { \ 37 if (kDocLoadErrorInit == error_in_doc_load_line) { \ 38 error_in_doc_load_line = __LINE__; \ 39 } \ 40 } \ 41 } while (0); 42 43 #define ON_LOAD_PASSED \ 44 do { \ 45 if (kDocLoadErrorInit == error_in_doc_load_line) \ 46 error_in_doc_load_line = kDocLoadErrorNone; \ 47 } while (0); 48 49 // Simple 1K buffer to hold the document passed through HandleDocumentLoad. 50 const uint32_t kMaxFileSize = 1024; 51 char buffer[kMaxFileSize]; 52 uint32_t buffer_pos = 0; 53 54 const char kKnownFileContents[] = 55 "This is just a test file so we can verify HandleDocumentLoad."; 56 57 void ReadCallback(void* user_data, int32_t pp_error_or_bytes) { 58 PP_Resource url_loader = reinterpret_cast<PP_Resource>(user_data); 59 60 EXPECT_ON_LOAD(pp_error_or_bytes >= PP_OK); 61 if (pp_error_or_bytes < PP_OK) { 62 PPBCore()->ReleaseResource(url_loader); 63 return; 64 } 65 66 if (PP_OK == pp_error_or_bytes) { 67 // Check the contents of the file against the known contents. 68 int diff = strncmp(buffer, 69 kKnownFileContents, 70 strlen(kKnownFileContents)); 71 EXPECT_ON_LOAD(diff == 0); 72 PPBURLLoader()->Close(url_loader); 73 PPBCore()->ReleaseResource(url_loader); 74 ON_LOAD_PASSED; 75 } else { 76 buffer_pos += pp_error_or_bytes; 77 PP_CompletionCallback callback = 78 PP_MakeCompletionCallback(ReadCallback, user_data); 79 pp_error_or_bytes = 80 PPBURLLoader()->ReadResponseBody(url_loader, 81 buffer + buffer_pos, 82 kMaxFileSize - buffer_pos, 83 callback); 84 EXPECT(pp_error_or_bytes == PP_OK_COMPLETIONPENDING); 85 } 86 } 87 88 PP_Bool HandleDocumentLoad(PP_Instance instance, 89 PP_Resource url_loader) { 90 // The browser will release url_loader after this method returns. We need to 91 // keep it around until we have read all bytes or get an error. 92 PPBCore()->AddRefResource(url_loader); 93 void* user_data = reinterpret_cast<void*>(url_loader); 94 PP_CompletionCallback callback = 95 PP_MakeCompletionCallback(ReadCallback, user_data); 96 int32_t pp_error_or_bytes = PPBURLLoader()->ReadResponseBody(url_loader, 97 buffer, 98 kMaxFileSize, 99 callback); 100 EXPECT(pp_error_or_bytes == PP_OK_COMPLETIONPENDING); 101 return PP_TRUE; 102 } 103 104 const PPP_Instance ppp_instance_interface = { 105 DidCreateDefault, 106 DidDestroyDefault, 107 DidChangeViewDefault, 108 DidChangeFocusDefault, 109 HandleDocumentLoad 110 }; 111 112 // This tests PPP_Instance::HandleDocumentLoad. 113 void TestHandleDocumentLoad() { 114 if (error_in_doc_load_line != kDocLoadErrorNone) { 115 char error[1024]; 116 snprintf(error, sizeof(error), 117 "ERROR at %s:%d: Document Load Failed\n", 118 __FILE__, error_in_doc_load_line); 119 fprintf(stderr, "%s", error); 120 PostTestMessage(__FUNCTION__, error); 121 } 122 TEST_PASSED; 123 } 124 125 // This tests PPB_Instance::IsFullFrame when the plugin is full frame. 126 // Other conditions for IsFullFrame are tested by ppb_instance tests. 127 void TestIsFullFrame() { 128 PP_Bool full_frame = PPBInstance()->IsFullFrame(pp_instance()); 129 EXPECT(full_frame == PP_TRUE); 130 TEST_PASSED; 131 } 132 133 134 } // namespace 135 136 137 void SetupTests() { 138 RegisterTest("TestHandleDocumentLoad", TestHandleDocumentLoad); 139 RegisterTest("TestIsFullFrame", TestIsFullFrame); 140 } 141 142 void SetupPluginInterfaces() { 143 RegisterPluginInterface(PPP_INSTANCE_INTERFACE, &ppp_instance_interface); 144 } 145