1/* 2 * Copyright (c) 2012 The Chromium Authors. All rights reserved. 3 * Use of this source code is governed by a BSD-style license that can be 4 * found in the LICENSE file. 5 */ 6 7#include "native_client/tests/inbrowser_test_runner/test_runner.h" 8 9#include <stdio.h> 10#include <string.h> 11 12#include "ppapi/native_client/src/shared/ppapi_proxy/ppruntime.h" 13 14#include "ppapi/c/pp_bool.h" 15#include "ppapi/c/pp_errors.h" 16#include "ppapi/c/pp_var.h" 17#include "ppapi/c/ppb_messaging.h" 18#include "ppapi/c/ppb_var.h" 19#include "ppapi/c/ppp.h" 20#include "ppapi/c/ppp_instance.h" 21#include "ppapi/c/ppp_messaging.h" 22 23 24/* 25 * Remembers the callback that actually performs the tests once the browser 26 * has posted a message to run the test. 27 */ 28static int (*g_test_func)(void); 29 30/* 31 * Browser interfaces invoked by the plugin. 32 */ 33static PPB_GetInterface g_get_browser_interface; 34const static PPB_Messaging *g_browser_messaging; 35const static PPB_Var *g_browser_var; 36 37 38/*************************************************************************** 39 * The entry point invoked by tests using this library. 40 **************************************************************************/ 41int RunTests(int (*test_func)(void)) { 42 /* Turn off stdout buffering to aid debugging in case of a crash. */ 43 setvbuf(stdout, NULL, _IONBF, 0); 44 if (getenv("OUTSIDE_BROWSER") != NULL) { 45 return test_func(); 46 } else { 47 g_test_func = test_func; 48 return PpapiPluginMain(); 49 } 50} 51 52int TestRunningInBrowser(void) { 53 return 1; 54} 55 56/*************************************************************************** 57 * PPP_Instance allows the browser to create an instance of the plugin. 58 **************************************************************************/ 59static PP_Bool PppInstanceDidCreate(PP_Instance instance, 60 uint32_t argc, 61 const char *argn[], 62 const char *argv[]) { 63 g_browser_messaging = (*g_get_browser_interface)(PPB_MESSAGING_INTERFACE); 64 g_browser_var = (*g_get_browser_interface)(PPB_VAR_INTERFACE); 65 return PP_TRUE; 66} 67 68static void PppInstanceDidDestroy(PP_Instance instance) { 69 /* Do nothing. */ 70} 71 72static void PppInstanceDidChangeView(PP_Instance instance, PP_Resource view) { 73 /* Do nothing. */ 74} 75 76void PppInstanceDidChangeFocus(PP_Instance instance, PP_Bool has_focus) { 77 /* Do nothing. */ 78} 79 80PP_Bool PppInstanceHandleDocumentLoad(PP_Instance instance, 81 PP_Resource url_loader) { 82 /* Signal document loading failed. */ 83 return PP_FALSE; 84} 85 86static const PPP_Instance kPppInstance = { 87 PppInstanceDidCreate, 88 PppInstanceDidDestroy, 89 PppInstanceDidChangeView, 90 PppInstanceDidChangeFocus, 91 PppInstanceHandleDocumentLoad 92}; 93 94/*************************************************************************** 95 * PPP_Messaging allows the browser to do postMessage to the plugin. 96 **************************************************************************/ 97static void PppMessagingHandleMessage(PP_Instance instance, 98 struct PP_Var message) { 99 const char *data; 100 uint32_t len; 101 static const char kStartMessage[] = "run_tests"; 102 int num_fails; 103 struct PP_Var result; 104 105 /* Ensure the start message is valid. */ 106 data = g_browser_var->VarToUtf8(message, &len); 107 if (len == 0) { 108 return; 109 } 110 if (strcmp(data, kStartMessage) != 0) { 111 return; 112 } 113 /* Run the tests. */ 114 num_fails = (*g_test_func)(); 115 /* Report the results. */ 116 if (num_fails == 0) { 117 static const char kPassed[] = "passed"; 118 result = g_browser_var->VarFromUtf8(kPassed, strlen(kPassed)); 119 } else { 120 static const char kFailed[] = "failed"; 121 result = g_browser_var->VarFromUtf8(kFailed, strlen(kFailed)); 122 } 123 124 g_browser_messaging->PostMessage(instance, result); 125} 126 127static const PPP_Messaging kPppMessaging = { 128 PppMessagingHandleMessage 129}; 130 131/*************************************************************************** 132 * The three entry points every PPAPI plugin must export. 133 **************************************************************************/ 134int32_t PPP_InitializeModule(PP_Module module, 135 PPB_GetInterface get_browser_interface) { 136 g_get_browser_interface = get_browser_interface; 137 return PP_OK; 138} 139 140void PPP_ShutdownModule(void) { 141} 142 143const void *PPP_GetInterface(const char *interface_name) { 144 /* Export PPP_Instance and PPP_Messaging. */ 145 if (strcmp(interface_name, PPP_INSTANCE_INTERFACE) == 0) { 146 return (const void*) &kPppInstance; 147 } 148 if (strcmp(interface_name, PPP_MESSAGING_INTERFACE) == 0) { 149 return (const void*) &kPppMessaging; 150 } 151 return NULL; 152} 153