summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordmichael@chromium.org <dmichael@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-12-22 08:35:52 +0000
committerdmichael@chromium.org <dmichael@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-12-22 08:35:52 +0000
commita732cec70e194fb770c0eee12430fcc416843364 (patch)
tree7ceafca7e48d4a5da68ef28f4b77f1b7ba21c2f3
parent02871872970e86b2255049ebe66c7f54ef50c721 (diff)
downloadchromium_src-a732cec70e194fb770c0eee12430fcc416843364.zip
chromium_src-a732cec70e194fb770c0eee12430fcc416843364.tar.gz
chromium_src-a732cec70e194fb770c0eee12430fcc416843364.tar.bz2
Add GetLiveVars to PPB_Testing_Dev. Fix leaks it uncovered.
BUG=108308,108314 TEST= Review URL: http://codereview.chromium.org/8982006 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@115503 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--ppapi/api/dev/ppb_testing_dev.idl15
-rw-r--r--ppapi/c/dev/ppb_testing_dev.h27
-rw-r--r--ppapi/cpp/dev/var_array_buffer_dev.cc1
-rw-r--r--ppapi/cpp/var.cc26
-rw-r--r--ppapi/native_client/src/shared/ppapi_proxy/browser_ppb_messaging_rpc_server.cc6
-rw-r--r--ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb.cc3
-rw-r--r--ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_testing.cc17
-rw-r--r--ppapi/native_client/src/shared/ppapi_proxy/proxy_var_cache.cc22
-rw-r--r--ppapi/native_client/src/shared/ppapi_proxy/proxy_var_cache.h4
-rw-r--r--ppapi/proxy/plugin_var_serialization_rules.cc2
-rw-r--r--ppapi/proxy/ppb_testing_proxy.cc16
-rw-r--r--ppapi/proxy/serialized_var.cc2
-rw-r--r--ppapi/proxy/serialized_var.h10
-rw-r--r--ppapi/proxy/serialized_var_unittest.cc162
-rw-r--r--ppapi/shared_impl/var_tracker.cc11
-rw-r--r--ppapi/shared_impl/var_tracker.h8
-rw-r--r--ppapi/tests/test_case.cc73
-rw-r--r--ppapi/tests/test_case.h16
-rw-r--r--ppapi/tests/test_directory_reader.cc2
-rw-r--r--ppapi/tests/test_file_io.cc2
-rw-r--r--ppapi/tests/test_file_ref.cc2
-rw-r--r--ppapi/tests/test_file_system.cc2
-rw-r--r--ppapi/tests/test_flash_fullscreen.cc2
-rw-r--r--ppapi/tests/test_fullscreen.cc2
-rw-r--r--ppapi/tests/test_graphics_2d.cc2
-rw-r--r--ppapi/tests/test_graphics_3d.cc2
-rw-r--r--ppapi/tests/test_input_event.cc2
-rw-r--r--ppapi/tests/test_memory.cc2
-rw-r--r--ppapi/tests/test_post_message.cc13
-rw-r--r--ppapi/tests/test_scrollbar.cc2
-rw-r--r--ppapi/tests/test_tcp_socket_private_shared.cc2
-rw-r--r--ppapi/tests/test_transport.cc2
-rw-r--r--ppapi/tests/test_udp_socket_private_shared.cc2
-rw-r--r--ppapi/tests/test_url_loader.cc2
-rw-r--r--ppapi/tests/test_var.cc3
-rw-r--r--ppapi/tests/test_var_deprecated.cc7
-rw-r--r--ppapi/tests/test_video_decoder.cc2
-rw-r--r--ppapi/tests/test_websocket.cc2
-rw-r--r--webkit/plugins/ppapi/message_channel.cc1
-rw-r--r--webkit/plugins/ppapi/plugin_module.cc16
40 files changed, 424 insertions, 71 deletions
diff --git a/ppapi/api/dev/ppb_testing_dev.idl b/ppapi/api/dev/ppb_testing_dev.idl
index 9e51b42..fa63fce 100644
--- a/ppapi/api/dev/ppb_testing_dev.idl
+++ b/ppapi/api/dev/ppb_testing_dev.idl
@@ -12,7 +12,8 @@
label Chrome {
M14 = 0.7,
M15 = 0.8,
- M17 = 0.9
+ M17 = 0.9,
+ M18 = 0.91
};
interface PPB_Testing_Dev {
@@ -114,4 +115,16 @@ interface PPB_Testing_Dev {
[version=0.9]
PP_Var GetDocumentURL([in] PP_Instance instance,
[out] PP_URLComponents_Dev components);
+
+ /**
+ * Fetches up to |array_size| active PP_Vars in the tracker. Returns the
+ * number of vars in the tracker. The active vars are written to |live_vars|
+ * contiguously starting at index 0. The vars are not in any particular order.
+ * If the number of live vars is greater than |array_size|, then an arbitrary
+ * subset of |array_size| vars is written to |live_vars|. The reference count
+ * of the returned PP_Vars will *not* be affected by this call.
+ */
+ [version=0.91]
+ uint32_t GetLiveVars([size_as=array_size] PP_Var[] live_vars,
+ [in] uint32_t array_size);
};
diff --git a/ppapi/c/dev/ppb_testing_dev.h b/ppapi/c/dev/ppb_testing_dev.h
index c892f6b..e52eeb2 100644
--- a/ppapi/c/dev/ppb_testing_dev.h
+++ b/ppapi/c/dev/ppb_testing_dev.h
@@ -3,7 +3,7 @@
* found in the LICENSE file.
*/
-/* From dev/ppb_testing_dev.idl modified Wed Dec 14 12:58:12 2011. */
+/* From dev/ppb_testing_dev.idl modified Fri Dec 16 16:08:07 2011. */
#ifndef PPAPI_C_DEV_PPB_TESTING_DEV_H_
#define PPAPI_C_DEV_PPB_TESTING_DEV_H_
@@ -20,7 +20,8 @@
#define PPB_TESTING_DEV_INTERFACE_0_7 "PPB_Testing(Dev);0.7"
#define PPB_TESTING_DEV_INTERFACE_0_8 "PPB_Testing(Dev);0.8"
#define PPB_TESTING_DEV_INTERFACE_0_9 "PPB_Testing(Dev);0.9"
-#define PPB_TESTING_DEV_INTERFACE PPB_TESTING_DEV_INTERFACE_0_9
+#define PPB_TESTING_DEV_INTERFACE_0_91 "PPB_Testing(Dev);0.91"
+#define PPB_TESTING_DEV_INTERFACE PPB_TESTING_DEV_INTERFACE_0_91
/**
* @file
@@ -124,6 +125,15 @@ struct PPB_Testing_Dev {
*/
struct PP_Var (*GetDocumentURL)(PP_Instance instance,
struct PP_URLComponents_Dev* components);
+ /**
+ * Fetches up to |array_size| active PP_Vars in the tracker. Returns the
+ * number of vars in the tracker. The active vars are written to |live_vars|
+ * contiguously starting at index 0. The vars are not in any particular order.
+ * If the number of live vars is greater than |array_size|, then an arbitrary
+ * subset of |array_size| vars is written to |live_vars|. The reference count
+ * of the returned PP_Vars will *not* be affected by this call.
+ */
+ uint32_t (*GetLiveVars)(struct PP_Var live_vars[], uint32_t array_size);
};
struct PPB_Testing_Dev_0_7 {
@@ -146,6 +156,19 @@ struct PPB_Testing_Dev_0_8 {
PP_Bool (*IsOutOfProcess)();
void (*SimulateInputEvent)(PP_Instance instance, PP_Resource input_event);
};
+
+struct PPB_Testing_Dev_0_9 {
+ PP_Bool (*ReadImageData)(PP_Resource device_context_2d,
+ PP_Resource image,
+ const struct PP_Point* top_left);
+ void (*RunMessageLoop)(PP_Instance instance);
+ void (*QuitMessageLoop)(PP_Instance instance);
+ uint32_t (*GetLiveObjectsForInstance)(PP_Instance instance);
+ PP_Bool (*IsOutOfProcess)();
+ void (*SimulateInputEvent)(PP_Instance instance, PP_Resource input_event);
+ struct PP_Var (*GetDocumentURL)(PP_Instance instance,
+ struct PP_URLComponents_Dev* components);
+};
/**
* @}
*/
diff --git a/ppapi/cpp/dev/var_array_buffer_dev.cc b/ppapi/cpp/dev/var_array_buffer_dev.cc
index 4ce6215..61f697e 100644
--- a/ppapi/cpp/dev/var_array_buffer_dev.cc
+++ b/ppapi/cpp/dev/var_array_buffer_dev.cc
@@ -32,6 +32,7 @@ VarArrayBuffer_Dev::VarArrayBuffer_Dev(uint32_t size_in_bytes)
: buffer_(NULL) {
if (has_interface<PPB_VarArrayBuffer_Dev>()) {
var_ = get_interface<PPB_VarArrayBuffer_Dev>()->Create(size_in_bytes);
+ needs_release_ = true;
buffer_ = Map();
} else {
PP_NOTREACHED();
diff --git a/ppapi/cpp/var.cc b/ppapi/cpp/var.cc
index 2b52f04..512fd00 100644
--- a/ppapi/cpp/var.cc
+++ b/ppapi/cpp/var.cc
@@ -104,7 +104,7 @@ Var::Var(const std::string& utf8_str) {
Var::Var(const Var& other) {
var_ = other.var_;
if (NeedsRefcounting(var_)) {
- if (has_interface<PPB_Var>()) {
+ if (has_interface<PPB_Var_1_0>()) {
needs_release_ = true;
get_interface<PPB_Var_1_0>()->AddRef(var_);
} else {
@@ -117,7 +117,7 @@ Var::Var(const Var& other) {
}
Var::~Var() {
- if (needs_release_ && has_interface<PPB_Var>())
+ if (needs_release_ && has_interface<PPB_Var_1_0>())
get_interface<PPB_Var_1_0>()->Release(var_);
}
@@ -132,8 +132,8 @@ Var& Var::operator=(const Var& other) {
// object to itself by addrefing the new one before releasing the old one.
bool old_needs_release = needs_release_;
if (NeedsRefcounting(other.var_)) {
- // Assume we already has_interface<PPB_Var> for refcounted vars or else we
- // couldn't have created them in the first place.
+ // Assume we already has_interface<PPB_Var_1_0> for refcounted vars or else
+ // we couldn't have created them in the first place.
needs_release_ = true;
get_interface<PPB_Var_1_0>()->AddRef(other.var_);
} else {
@@ -203,7 +203,7 @@ std::string Var::AsString() const {
return std::string();
}
- if (!has_interface<PPB_Var>())
+ if (!has_interface<PPB_Var_1_0>())
return std::string();
uint32_t len;
const char* str = get_interface<PPB_Var_1_0>()->VarToUtf8(var_, &len);
@@ -213,18 +213,18 @@ std::string Var::AsString() const {
std::string Var::DebugString() const {
char buf[256];
if (is_undefined()) {
- snprintf(buf, sizeof(buf), "Var<UNDEFINED>");
+ snprintf(buf, sizeof(buf), "Var(UNDEFINED)");
} else if (is_null()) {
- snprintf(buf, sizeof(buf), "Var<NULL>");
+ snprintf(buf, sizeof(buf), "Var(NULL)");
} else if (is_bool()) {
- snprintf(buf, sizeof(buf), AsBool() ? "Var<true>" : "Var<false>");
+ snprintf(buf, sizeof(buf), AsBool() ? "Var(true)" : "Var(false)");
} else if (is_int()) {
// Note that the following static_cast is necessary because
// NativeClient's int32_t is actually "long".
// TODO(sehr,polina): remove this after newlib is changed.
- snprintf(buf, sizeof(buf), "Var<%d>", static_cast<int>(AsInt()));
+ snprintf(buf, sizeof(buf), "Var(%d)", static_cast<int>(AsInt()));
} else if (is_double()) {
- snprintf(buf, sizeof(buf), "Var<%f>", AsDouble());
+ snprintf(buf, sizeof(buf), "Var(%f)", AsDouble());
} else if (is_string()) {
char format[] = "Var<'%s'>";
size_t decoration = sizeof(format) - 2; // The %s is removed.
@@ -235,8 +235,12 @@ std::string Var::DebugString() const {
str.append("...");
}
snprintf(buf, sizeof(buf), format, str.c_str());
+ } else if (is_array_buffer()) {
+ // TODO(dmichael): We could make this dump hex. Maybe DebugString should be
+ // virtual?
+ snprintf(buf, sizeof(buf), "Var(ARRAY_BUFFER)");
} else if (is_object()) {
- snprintf(buf, sizeof(buf), "Var<OBJECT>");
+ snprintf(buf, sizeof(buf), "Var(OBJECT)");
}
return buf;
}
diff --git a/ppapi/native_client/src/shared/ppapi_proxy/browser_ppb_messaging_rpc_server.cc b/ppapi/native_client/src/shared/ppapi_proxy/browser_ppb_messaging_rpc_server.cc
index 08b525b..d2d35e5 100644
--- a/ppapi/native_client/src/shared/ppapi_proxy/browser_ppb_messaging_rpc_server.cc
+++ b/ppapi/native_client/src/shared/ppapi_proxy/browser_ppb_messaging_rpc_server.cc
@@ -13,6 +13,7 @@
#endif
using ppapi_proxy::PPBMessagingInterface;
+using ppapi_proxy::PPBVarInterface;
using ppapi_proxy::DebugPrintf;
using ppapi_proxy::DeserializeTo;
@@ -30,6 +31,11 @@ void PpbMessagingRpcServer::PPB_Messaging_PostMessage(
return;
PPBMessagingInterface()->PostMessage(instance, message);
+
+ // In the case of a string, DeserializeTo creates a PP_Var with a reference-
+ // count of 1. We must release the var, or it will stay in the browser's map.
+ PPBVarInterface()->Release(message);
+
DebugPrintf("PPB_Messaging::PostMessage: instance=%"NACL_PRIu32"\n",
instance);
diff --git a/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb.cc b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb.cc
index ab894f7..d4d2511 100644
--- a/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb.cc
+++ b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb.cc
@@ -83,9 +83,8 @@ InterfaceMapElement interface_map[] = {
{ PPB_SCROLLBAR_DEV_INTERFACE, PluginScrollbar::GetInterface(), true },
{ PPB_TCPSOCKET_PRIVATE_INTERFACE, PluginTCPSocketPrivate::GetInterface(),
true },
- { PPB_TESTING_DEV_INTERFACE_0_7, PluginTesting::GetInterface(), true },
- { PPB_TESTING_DEV_INTERFACE_0_8, PluginTesting::GetInterface(), true },
{ PPB_TESTING_DEV_INTERFACE_0_9, PluginTesting::GetInterface(), true },
+ { PPB_TESTING_DEV_INTERFACE, PluginTesting::GetInterface(), true },
{ PPB_UDPSOCKET_PRIVATE_INTERFACE, PluginUDPSocketPrivate::GetInterface(),
true },
{ PPB_URLLOADER_INTERFACE, PluginURLLoader::GetInterface(), true },
diff --git a/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_testing.cc b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_testing.cc
index 5c81a2a..dbd01b44 100644
--- a/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_testing.cc
+++ b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_testing.cc
@@ -6,12 +6,14 @@
#include <cstddef>
#include <new>
+#include <vector>
#include "native_client/src/include/nacl_scoped_ptr.h"
#include "native_client/src/include/portability.h"
#include "native_client/src/shared/ppapi_proxy/object_serialize.h"
#include "native_client/src/shared/ppapi_proxy/plugin_globals.h"
#include "native_client/src/shared/ppapi_proxy/plugin_callback.h"
+#include "native_client/src/shared/ppapi_proxy/proxy_var_cache.h"
#include "native_client/src/shared/ppapi_proxy/utility.h"
#include "ppapi/c/dev/ppb_testing_dev.h"
#include "ppapi/c/pp_completion_callback.h"
@@ -145,6 +147,18 @@ struct PP_Var GetDocumentURL(PP_Instance instance,
return url;
}
+// TODO(dmichael): Ideally we could get a way to check the number of vars in the
+// host-side tracker when running NaCl, to make sure the proxy does not leak
+// host-side vars.
+uint32_t GetLiveVars(PP_Var live_vars[], uint32_t array_size) {
+ std::vector<PP_Var> vars = ProxyVarCache::GetInstance().GetLiveVars();
+ for (size_t i = 0u;
+ i < std::min(static_cast<size_t>(array_size), vars.size());
+ ++i)
+ live_vars[i] = vars[i];
+ return vars.size();
+}
+
} // namespace
const PPB_Testing_Dev* PluginTesting::GetInterface() {
@@ -155,7 +169,8 @@ const PPB_Testing_Dev* PluginTesting::GetInterface() {
GetLiveObjectsForInstance,
IsOutOfProcess,
SimulateInputEvent,
- GetDocumentURL
+ GetDocumentURL,
+ GetLiveVars
};
return &testing_interface;
}
diff --git a/ppapi/native_client/src/shared/ppapi_proxy/proxy_var_cache.cc b/ppapi/native_client/src/shared/ppapi_proxy/proxy_var_cache.cc
index 636302c..b172869 100644
--- a/ppapi/native_client/src/shared/ppapi_proxy/proxy_var_cache.cc
+++ b/ppapi/native_client/src/shared/ppapi_proxy/proxy_var_cache.cc
@@ -16,6 +16,17 @@ namespace {
pthread_mutex_t mu = PTHREAD_MUTEX_INITIALIZER;
+// Convert the given SharedProxyVar to a PP_Var, incrementing the reference
+// count by 1.
+PP_Var GetPPVar(const SharedProxyVar& proxy_var) {
+ PP_Var var;
+ var.type = proxy_var->pp_var_type();
+ var.padding = 0;
+ var.value.as_id = proxy_var->id();
+ proxy_var->AddRef();
+ return var;
+}
+
} // namespace
ProxyVarCache* ProxyVarCache::cache_singleton = NULL;
@@ -86,4 +97,15 @@ SharedProxyVar ProxyVarCache::SharedProxyVarForVar(PP_Var pp_var) const {
return proxy_var;
}
+std::vector<PP_Var> ProxyVarCache::GetLiveVars() {
+ std::vector<PP_Var> live_vars;
+ pthread_mutex_lock(&mu);
+ for (ProxyVarDictionary::const_iterator iter(proxy_var_cache_.begin());
+ iter != proxy_var_cache_.end();
+ ++iter)
+ live_vars.push_back(GetPPVar(iter->second));
+ pthread_mutex_unlock(&mu);
+ return live_vars;
+}
+
} // namespace ppapi_proxy
diff --git a/ppapi/native_client/src/shared/ppapi_proxy/proxy_var_cache.h b/ppapi/native_client/src/shared/ppapi_proxy/proxy_var_cache.h
index 41c8d0c..6cec6d4 100644
--- a/ppapi/native_client/src/shared/ppapi_proxy/proxy_var_cache.h
+++ b/ppapi/native_client/src/shared/ppapi_proxy/proxy_var_cache.h
@@ -6,6 +6,7 @@
#define NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_PROXY_VAR_CACHE_H_
#include <map>
+#include <vector>
#include "native_client/src/include/nacl_memory.h"
#include "native_client/src/shared/ppapi_proxy/proxy_var.h"
@@ -48,6 +49,9 @@ class ProxyVarCache {
// Find the object in the cache associated with |pp_var|.
SharedProxyVar SharedProxyVarForVar(PP_Var pp_var) const;
+ // Return all live Vars in the tracker. Reference counts are incremented.
+ std::vector<PP_Var> GetLiveVars();
+
private:
// Return whether or not a var type is cached.
// Note to implementers: be sure to add to this function when adding new
diff --git a/ppapi/proxy/plugin_var_serialization_rules.cc b/ppapi/proxy/plugin_var_serialization_rules.cc
index 155c844..a4eea5b 100644
--- a/ppapi/proxy/plugin_var_serialization_rules.cc
+++ b/ppapi/proxy/plugin_var_serialization_rules.cc
@@ -136,6 +136,8 @@ void PluginVarSerializationRules::EndSendPassRef(const PP_Var& var,
if (var.type == PP_VARTYPE_OBJECT) {
var_tracker_->ReleaseHostObject(
static_cast<PluginDispatcher*>(dispatcher), var);
+ } else if (var.type == PP_VARTYPE_STRING) {
+ var_tracker_->ReleaseVar(var);
}
}
diff --git a/ppapi/proxy/ppb_testing_proxy.cc b/ppapi/proxy/ppb_testing_proxy.cc
index 77d1af0..32d5215 100644
--- a/ppapi/proxy/ppb_testing_proxy.cc
+++ b/ppapi/proxy/ppb_testing_proxy.cc
@@ -95,6 +95,19 @@ PP_Var GetDocumentURL(PP_Instance instance, PP_URLComponents_Dev* components) {
return enter.functions()->GetDocumentURL(instance, components);
}
+// TODO(dmichael): Ideally we could get a way to check the number of vars in the
+// host-side tracker when running out-of-process, to make sure the proxy does
+// not leak host-side vars.
+uint32_t GetLiveVars(PP_Var live_vars[], uint32_t array_size) {
+ std::vector<PP_Var> vars =
+ PpapiGlobals::Get()->GetVarTracker()->GetLiveVars();
+ for (size_t i = 0u;
+ i < std::min(static_cast<size_t>(array_size), vars.size());
+ ++i)
+ live_vars[i] = vars[i];
+ return vars.size();
+}
+
const PPB_Testing_Dev testing_interface = {
&ReadImageData,
&RunMessageLoop,
@@ -102,7 +115,8 @@ const PPB_Testing_Dev testing_interface = {
&GetLiveObjectsForInstance,
&IsOutOfProcess,
&SimulateInputEvent,
- &GetDocumentURL
+ &GetDocumentURL,
+ &GetLiveVars
};
InterfaceProxy* CreateTestingProxy(Dispatcher* dispatcher) {
diff --git a/ppapi/proxy/serialized_var.cc b/ppapi/proxy/serialized_var.cc
index b892daf..f9d59e5 100644
--- a/ppapi/proxy/serialized_var.cc
+++ b/ppapi/proxy/serialized_var.cc
@@ -411,7 +411,7 @@ PP_Var* SerializedVarVectorReceiveInput::Get(Dispatcher* dispatcher,
uint32_t* array_size) {
deserialized_.resize(serialized_.size());
for (size_t i = 0; i < serialized_.size(); i++) {
- // The vector must be able to clean themselves up after this call is
+ // The vectors must be able to clean themselves up after this call is
// torn down.
serialized_[i].inner_->set_serialization_rules(
dispatcher->serialization_rules());
diff --git a/ppapi/proxy/serialized_var.h b/ppapi/proxy/serialized_var.h
index e75f480..c0cb1ac 100644
--- a/ppapi/proxy/serialized_var.h
+++ b/ppapi/proxy/serialized_var.h
@@ -184,7 +184,7 @@ class PPAPI_PROXY_EXPORT SerializedVar {
// void MyFunctionProxy(PP_Var param) {
// Send(new MyFunctionMsg(SerializedVarSendInput(dispatcher, param));
// }
-class SerializedVarSendInput : public SerializedVar {
+class PPAPI_PROXY_EXPORT SerializedVarSendInput : public SerializedVar {
public:
SerializedVarSendInput(Dispatcher* dispatcher, const PP_Var& var);
@@ -243,7 +243,7 @@ class PPAPI_PROXY_EXPORT ReceiveSerializedVarReturnValue
// ReceiveSerializedException se(dispatcher(), exception)
// Send(new PpapiHostMsg_Foo(&se));
// }
-class ReceiveSerializedException : public SerializedVar {
+class PPAPI_PROXY_EXPORT ReceiveSerializedException : public SerializedVar {
public:
ReceiveSerializedException(Dispatcher* dispatcher, PP_Var* exception);
~ReceiveSerializedException();
@@ -274,7 +274,7 @@ class ReceiveSerializedException : public SerializedVar {
// ReceiveSerializedVarVectorOutParam vect(dispatcher, count, vars);
// Send(new MyMsg(vect.OutParam()));
// }
-class ReceiveSerializedVarVectorOutParam {
+class PPAPI_PROXY_EXPORT ReceiveSerializedVarVectorOutParam {
public:
ReceiveSerializedVarVectorOutParam(Dispatcher* dispatcher,
uint32_t* output_count,
@@ -333,7 +333,7 @@ class PPAPI_PROXY_EXPORT SerializedVarReceiveInput {
// PP_Var* array = vector.Get(dispatcher, &size);
// MyFunction(size, array);
// }
-class SerializedVarVectorReceiveInput {
+class PPAPI_PROXY_EXPORT SerializedVarVectorReceiveInput {
public:
SerializedVarVectorReceiveInput(const std::vector<SerializedVar>& serialized);
~SerializedVarVectorReceiveInput();
@@ -415,7 +415,7 @@ class PPAPI_PROXY_EXPORT SerializedVarOutParam {
// For returning an array of PP_Vars to the other side and transferring
// ownership.
//
-class SerializedVarVectorOutParam {
+class PPAPI_PROXY_EXPORT SerializedVarVectorOutParam {
public:
SerializedVarVectorOutParam(std::vector<SerializedVar>* serialized);
~SerializedVarVectorOutParam();
diff --git a/ppapi/proxy/serialized_var_unittest.cc b/ppapi/proxy/serialized_var_unittest.cc
index 8ad6c99..150f5e7 100644
--- a/ppapi/proxy/serialized_var_unittest.cc
+++ b/ppapi/proxy/serialized_var_unittest.cc
@@ -11,13 +11,6 @@ namespace proxy {
namespace {
-PP_Var MakeStringVar(int64_t string_id) {
- PP_Var ret;
- ret.type = PP_VARTYPE_STRING;
- ret.value.as_id = string_id;
- return ret;
-}
-
PP_Var MakeObjectVar(int64_t object_id) {
PP_Var ret;
ret.type = PP_VARTYPE_OBJECT;
@@ -34,6 +27,95 @@ class SerializedVarTest : public PluginProxyTest {
// Tests output arguments in the plugin. This is when the host calls into the
// plugin and the plugin returns something via an out param, like an exception.
+TEST_F(SerializedVarTest, PluginSerializedVarInOutParam) {
+ PP_Var host_object = MakeObjectVar(0x31337);
+
+ PP_Var plugin_object;
+ {
+ // Receive the object param, we should be tracking it with no refcount, and
+ // no messages sent.
+ SerializedVarTestConstructor input(host_object);
+ SerializedVarReceiveInput receive_input(input);
+ plugin_object = receive_input.Get(plugin_dispatcher());
+ EXPECT_EQ(0, var_tracker().GetRefCountForObject(plugin_object));
+ EXPECT_EQ(0u, sink().message_count());
+
+ SerializedVar sv;
+ {
+ // The "OutParam" does its work in its destructor, it will write the
+ // information to the SerializedVar we passed in the constructor.
+ SerializedVarOutParam out_param(&sv);
+ // An out-param needs to pass a reference to the caller, so it's the
+ // responsibility of the plugin to bump the ref-count on an input
+ // parameter.
+ var_tracker().AddRefVar(plugin_object);
+ EXPECT_EQ(1, var_tracker().GetRefCountForObject(plugin_object));
+ // We should have informed the host that a reference was taken.
+ EXPECT_EQ(1u, sink().message_count());
+ *out_param.OutParam(plugin_dispatcher()) = plugin_object;
+ }
+
+ // The object should have transformed the plugin object back to the host
+ // object ID. Nothing in the var tracker should have changed yet, and no
+ // messages should have been sent.
+ SerializedVarTestReader reader(sv);
+ EXPECT_EQ(host_object.value.as_id, reader.GetIncompleteVar().value.as_id);
+ EXPECT_EQ(1, var_tracker().GetRefCountForObject(plugin_object));
+ EXPECT_EQ(1u, sink().message_count());
+ }
+
+ // The out param should have done an "end receive caller owned" on the plugin
+ // var serialization rules, which should have released the "track-with-no-
+ // reference" count in the var tracker as well as the 1 reference we passed
+ // back to the host, so the object should no longer be in the tracker. The
+ // reference we added has been removed, so another message should be sent to
+ // the host to tell it we're done with the object.
+ EXPECT_EQ(-1, var_tracker().GetRefCountForObject(plugin_object));
+ EXPECT_EQ(2u, sink().message_count());
+}
+
+// Tests output strings in the plugin. This is when the host calls into the
+// plugin with a string and the plugin returns it via an out param.
+TEST_F(SerializedVarTest, PluginSerializedStringVarInOutParam) {
+ PP_Var plugin_string;
+ const std::string kTestString("elite");
+ {
+ // Receive the string param. We should track it with 1 refcount.
+ SerializedVarTestConstructor input(kTestString);
+ SerializedVarReceiveInput receive_input(input);
+ plugin_string = receive_input.Get(plugin_dispatcher());
+ EXPECT_EQ(1, var_tracker().GetRefCountForObject(plugin_string));
+ EXPECT_EQ(0u, sink().message_count());
+
+ SerializedVar sv;
+ {
+ // The "OutParam" does its work in its destructor, it will write the
+ // information to the SerializedVar we passed in the constructor.
+ SerializedVarOutParam out_param(&sv);
+ // An out-param needs to pass a reference to the caller, so it's the
+ // responsibility of the plugin to bump the ref-count of an input
+ // parameter.
+ var_tracker().AddRefVar(plugin_string);
+ EXPECT_EQ(2, var_tracker().GetRefCountForObject(plugin_string));
+ EXPECT_EQ(0u, sink().message_count());
+ *out_param.OutParam(plugin_dispatcher()) = plugin_string;
+ }
+
+ // The SerializedVar should have set the string value internally. Nothing in
+ // the var tracker should have changed yet, and no messages should have been
+ // sent.
+ SerializedVarTestReader reader(sv);
+ EXPECT_EQ(kTestString, reader.GetString());
+ EXPECT_EQ(2, var_tracker().GetRefCountForObject(plugin_string));
+ EXPECT_EQ(0u, sink().message_count());
+ }
+ // The reference the string had initially should be gone, and the reference we
+ // passed to the host should also be gone, so the string should be removed.
+ EXPECT_EQ(-1, var_tracker().GetRefCountForObject(plugin_string));
+ EXPECT_EQ(0u, sink().message_count());
+}
+
+// Tests receiving an argument and passing it back out as an output parameter.
TEST_F(SerializedVarTest, PluginSerializedVarOutParam) {
PP_Var host_object = MakeObjectVar(0x31337);
@@ -111,6 +193,72 @@ TEST_F(SerializedVarTest, PluginReceiveInput) {
EXPECT_EQ(-1, var_tracker().GetRefCountForObject(plugin_object));
}
+// Tests the case that the plugin receives the same vars twice as an input
+// parameter (not passing ownership) within a vector.
+TEST_F(SerializedVarTest, PluginVectorReceiveInput) {
+ PP_Var host_object = MakeObjectVar(0x31337);
+
+ PP_Var* plugin_objects;
+ PP_Var* plugin_objects2;
+ {
+ // Receive the params. The object should be tracked with no refcount and
+ // no messages sent. The string should is plugin-side only and should have
+ // a reference-count of 1.
+ std::vector<SerializedVar> input1;
+ input1.push_back(SerializedVarTestConstructor(host_object));
+ input1.push_back(SerializedVarTestConstructor("elite"));
+ SerializedVarVectorReceiveInput receive_input(input1);
+ uint32_t array_size = 0;
+ plugin_objects = receive_input.Get(plugin_dispatcher(), &array_size);
+ ASSERT_EQ(2u, array_size);
+ EXPECT_EQ(0, var_tracker().GetRefCountForObject(plugin_objects[0]));
+ EXPECT_EQ(1, var_tracker().GetRefCountForObject(plugin_objects[1]));
+ EXPECT_EQ(0u, sink().message_count());
+
+ // Receive the second param, it should be resolved to the same plugin
+ // object and there should still be no refcount.
+ std::vector<SerializedVar> input2;
+ input2.push_back(SerializedVarTestConstructor(host_object));
+ input2.push_back(SerializedVarTestConstructor("elite"));
+ SerializedVarVectorReceiveInput receive_input2(input2);
+ uint32_t array_size2 = 0;
+ plugin_objects2 = receive_input2.Get(plugin_dispatcher(), &array_size2);
+ ASSERT_EQ(2u, array_size2);
+ EXPECT_EQ(plugin_objects[0].value.as_id, plugin_objects2[0].value.as_id);
+ EXPECT_EQ(0, var_tracker().GetRefCountForObject(plugin_objects[0]));
+ // Strings get re-created with a new ID. We don't try to reuse strings in
+ // the tracker, so the string should get a new ID.
+ EXPECT_NE(plugin_objects[1].value.as_id, plugin_objects2[1].value.as_id);
+ EXPECT_EQ(1, var_tracker().GetRefCountForObject(plugin_objects2[1]));
+ EXPECT_EQ(0u, sink().message_count());
+
+ // Take a reference to the object, as if the plugin was using it, and then
+ // release it, we should still be tracking the object since the
+ // ReceiveInputs keep the "track_with_no_reference_count" alive until
+ // they're destroyed.
+ var_tracker().AddRefVar(plugin_objects[0]);
+ EXPECT_EQ(1, var_tracker().GetRefCountForObject(plugin_objects[0]));
+ var_tracker().ReleaseVar(plugin_objects[0]);
+ EXPECT_EQ(0, var_tracker().GetRefCountForObject(plugin_objects[0]));
+ EXPECT_EQ(2u, sink().message_count());
+
+ // Take a reference to a string and then release it. Make sure no messages
+ // are sent.
+ uint32_t old_message_count = sink().message_count();
+ var_tracker().AddRefVar(plugin_objects[1]);
+ EXPECT_EQ(2, var_tracker().GetRefCountForObject(plugin_objects[1]));
+ var_tracker().ReleaseVar(plugin_objects[1]);
+ EXPECT_EQ(1, var_tracker().GetRefCountForObject(plugin_objects[1]));
+ EXPECT_EQ(old_message_count, sink().message_count());
+ }
+
+ // Since we didn't keep any refs to the objects or strings, so they should
+ // have been freed.
+ EXPECT_EQ(-1, var_tracker().GetRefCountForObject(plugin_objects[0]));
+ EXPECT_EQ(-1, var_tracker().GetRefCountForObject(plugin_objects[1]));
+ EXPECT_EQ(-1, var_tracker().GetRefCountForObject(plugin_objects2[1]));
+}
+
// Tests the plugin receiving a var as a return value from the browser
// two different times (passing ownership).
TEST_F(SerializedVarTest, PluginReceiveReturn) {
diff --git a/ppapi/shared_impl/var_tracker.cc b/ppapi/shared_impl/var_tracker.cc
index 287e7b1..58c715c 100644
--- a/ppapi/shared_impl/var_tracker.cc
+++ b/ppapi/shared_impl/var_tracker.cc
@@ -149,6 +149,17 @@ PP_Var VarTracker::MakeArrayBufferPPVar(uint32 size_in_bytes) {
return array_buffer->GetPPVar();
}
+std::vector<PP_Var> VarTracker::GetLiveVars() {
+ std::vector<PP_Var> var_vector;
+ var_vector.reserve(live_vars_.size());
+ for (VarMap::const_iterator iter = live_vars_.begin();
+ iter != live_vars_.end();
+ ++iter) {
+ var_vector.push_back(iter->second.var->GetPPVar());
+ }
+ return var_vector;
+}
+
void VarTracker::TrackedObjectGettingOneRef(VarMap::const_iterator obj) {
// Anybody using tracked objects should override this.
NOTREACHED();
diff --git a/ppapi/shared_impl/var_tracker.h b/ppapi/shared_impl/var_tracker.h
index a2debe0..4dc8a2d 100644
--- a/ppapi/shared_impl/var_tracker.h
+++ b/ppapi/shared_impl/var_tracker.h
@@ -5,6 +5,8 @@
#ifndef PPAPI_SHARED_IMPL_VAR_TRACKER_H_
#define PPAPI_SHARED_IMPL_VAR_TRACKER_H_
+#include <vector>
+
#include "base/basictypes.h"
#include "base/hash_tables.h"
#include "base/memory/ref_counted.h"
@@ -60,6 +62,12 @@ class PPAPI_SHARED_EXPORT VarTracker {
// that references it and has an initial reference-count of 1.
PP_Var MakeArrayBufferPPVar(uint32 size_in_bytes);
+ // Return a vector containing all PP_Vars that are in the tracker. This is
+ // to help implement PPB_Testing_Dev.GetLiveVars and should generally not be
+ // used in production code. The PP_Vars are returned in no particular order,
+ // and their reference counts are unaffected.
+ std::vector<PP_Var> GetLiveVars();
+
protected:
struct VarInfo {
VarInfo();
diff --git a/ppapi/tests/test_case.cc b/ppapi/tests/test_case.cc
index bcee6c3..e6164e0 100644
--- a/ppapi/tests/test_case.cc
+++ b/ppapi/tests/test_case.cc
@@ -13,6 +13,10 @@ TestCase::TestCase(TestingInstance* instance)
: instance_(instance),
testing_interface_(NULL),
force_async_(false) {
+ // Get the testing_interface_ if it is available, so that we can do Resource
+ // and Var checks on shutdown (see CheckResourcesAndVars). If it is not
+ // available, testing_interface_ will be NULL. Some tests do not require it.
+ testing_interface_ = GetTestingInterface();
}
TestCase::~TestCase() {
@@ -50,6 +54,20 @@ pp::VarPrivate TestCase::GetTestObject() {
}
#endif
+bool TestCase::CheckTestingInterface() {
+ testing_interface_ = GetTestingInterface();
+ if (!testing_interface_) {
+ // Give a more helpful error message for the testing interface being gone
+ // since that needs special enabling in Chrome.
+ instance_->AppendError("This test needs the testing interface, which is "
+ "not currently available. In Chrome, use "
+ "--enable-pepper-testing when launching.");
+ return false;
+ }
+
+ return true;
+}
+
void TestCase::HandleMessage(const pp::Var& message_data) {
}
@@ -66,20 +84,6 @@ pp::deprecated::ScriptableObject* TestCase::CreateTestObject() {
}
#endif
-bool TestCase::InitTestingInterface() {
- testing_interface_ = GetTestingInterface();
- if (!testing_interface_) {
- // Give a more helpful error message for the testing interface being gone
- // since that needs special enabling in Chrome.
- instance_->AppendError("This test needs the testing interface, which is "
- "not currently available. In Chrome, use "
- "--enable-pepper-testing when launching.");
- return false;
- }
-
- return true;
-}
-
bool TestCase::EnsureRunningOverHTTP() {
if (instance_->protocol() != "http:") {
instance_->AppendError("This test needs to be run over HTTP.");
@@ -94,3 +98,44 @@ bool TestCase::MatchesFilter(const std::string& test_name,
return filter.empty() || (test_name == filter);
}
+std::string TestCase::CheckResourcesAndVars() {
+ std::string errors;
+ if (testing_interface_) {
+ // TODO(dmichael): Fix tests that leak resources and enable the following:
+ /*
+ uint32_t leaked_resources =
+ testing_interface_->GetLiveObjectsForInstance(instance_->pp_instance());
+ if (leaked_resources) {
+ std::ostringstream output;
+ output << "FAILED: Test leaked " << leaked_resources << " resources.\n";
+ errors += output.str();
+ }
+ */
+ const uint32_t kVarsToPrint = 10;
+ PP_Var vars[kVarsToPrint];
+ uint32_t leaked_vars = testing_interface_->GetLiveVars(vars, kVarsToPrint);
+ uint32_t tracked_vars = leaked_vars;
+#if !(defined __native_client__)
+ // Don't count test_object_ as a leak.
+ if (test_object_.pp_var().type > PP_VARTYPE_DOUBLE)
+ --leaked_vars;
+#endif
+ if (leaked_vars) {
+ std::ostringstream output;
+ output << "Test leaked " << leaked_vars << " vars (printing at most "
+ << kVarsToPrint <<"):<p>";
+ errors += output.str();
+ for (uint32_t i = 0; i < std::min(tracked_vars, kVarsToPrint); ++i) {
+ pp::Var leaked_var(pp::Var::PassRef(), vars[i]);
+#if (defined __native_client__)
+ errors += leaked_var.DebugString() + "<p>";
+#else
+ if (!(leaked_var == test_object_))
+ errors += leaked_var.DebugString() + "<p>";
+#endif
+ }
+ }
+ }
+ return errors;
+}
+
diff --git a/ppapi/tests/test_case.h b/ppapi/tests/test_case.h
index 8ea3aef..75cafda 100644
--- a/ppapi/tests/test_case.h
+++ b/ppapi/tests/test_case.h
@@ -80,8 +80,10 @@ class TestCase {
virtual pp::deprecated::ScriptableObject* CreateTestObject();
#endif
- // Initializes the testing interface.
- bool InitTestingInterface();
+ // Checks whether the testing interface is available. Returns true if it is,
+ // false otherwise. If it is not available, adds a descriptive error. This is
+ // for use by tests that require the testing interface.
+ bool CheckTestingInterface();
// Makes sure the test is run over HTTP.
bool EnsureRunningOverHTTP();
@@ -90,6 +92,11 @@ class TestCase {
// (a) filter is empty or (b) test_name and filter match exactly.
bool MatchesFilter(const std::string& test_name, const std::string& filter);
+ // Check for leaked resources and vars at the end of the test. If any exist,
+ // return a string with some information about the error. Otherwise, return
+ // an empty string.
+ std::string CheckResourcesAndVars();
+
// Pointer to the instance that owns us.
TestingInstance* instance_;
@@ -150,7 +157,10 @@ class TestCaseFactory {
#define RUN_TEST(name, test_filter) \
if (MatchesFilter(#name, test_filter)) { \
force_async_ = false; \
- instance_->LogTest(#name, Test##name()); \
+ std::string error_message = Test##name(); \
+ if (error_message.empty()) \
+ error_message = CheckResourcesAndVars(); \
+ instance_->LogTest(#name, error_message); \
}
#define RUN_TEST_WITH_REFERENCE_CHECK(name, test_filter) \
diff --git a/ppapi/tests/test_directory_reader.cc b/ppapi/tests/test_directory_reader.cc
index 3823f29..254a355 100644
--- a/ppapi/tests/test_directory_reader.cc
+++ b/ppapi/tests/test_directory_reader.cc
@@ -72,7 +72,7 @@ int32_t DeleteDirectoryRecursively(pp::FileRef* dir,
} // namespace
bool TestDirectoryReader::Init() {
- return InitTestingInterface() && EnsureRunningOverHTTP();
+ return CheckTestingInterface() && EnsureRunningOverHTTP();
}
void TestDirectoryReader::RunTests(const std::string& filter) {
diff --git a/ppapi/tests/test_file_io.cc b/ppapi/tests/test_file_io.cc
index 057fdef..f5235e1 100644
--- a/ppapi/tests/test_file_io.cc
+++ b/ppapi/tests/test_file_io.cc
@@ -109,7 +109,7 @@ int32_t WriteEntireBuffer(PP_Instance instance,
} // namespace
bool TestFileIO::Init() {
- return InitTestingInterface() && EnsureRunningOverHTTP();
+ return CheckTestingInterface() && EnsureRunningOverHTTP();
}
void TestFileIO::RunTests(const std::string& filter) {
diff --git a/ppapi/tests/test_file_ref.cc b/ppapi/tests/test_file_ref.cc
index b17450d..0e42d1c 100644
--- a/ppapi/tests/test_file_ref.cc
+++ b/ppapi/tests/test_file_ref.cc
@@ -41,7 +41,7 @@ std::string ReportMismatch(const std::string& method_name,
} // namespace
bool TestFileRef::Init() {
- return InitTestingInterface() && EnsureRunningOverHTTP();
+ return CheckTestingInterface() && EnsureRunningOverHTTP();
}
void TestFileRef::RunTests(const std::string& filter) {
diff --git a/ppapi/tests/test_file_system.cc b/ppapi/tests/test_file_system.cc
index 2b5a0c5..8c05d42 100644
--- a/ppapi/tests/test_file_system.cc
+++ b/ppapi/tests/test_file_system.cc
@@ -14,7 +14,7 @@
REGISTER_TEST_CASE(FileSystem);
bool TestFileSystem::Init() {
- return InitTestingInterface() && EnsureRunningOverHTTP();
+ return CheckTestingInterface() && EnsureRunningOverHTTP();
}
void TestFileSystem::RunTests(const std::string& filter) {
diff --git a/ppapi/tests/test_flash_fullscreen.cc b/ppapi/tests/test_flash_fullscreen.cc
index f7f122b..0d49605 100644
--- a/ppapi/tests/test_flash_fullscreen.cc
+++ b/ppapi/tests/test_flash_fullscreen.cc
@@ -46,7 +46,7 @@ TestFlashFullscreen::TestFlashFullscreen(TestingInstance* instance)
}
bool TestFlashFullscreen::Init() {
- return InitTestingInterface();
+ return CheckTestingInterface();
}
void TestFlashFullscreen::RunTests(const std::string& filter) {
diff --git a/ppapi/tests/test_fullscreen.cc b/ppapi/tests/test_fullscreen.cc
index c531c02..f2b204e 100644
--- a/ppapi/tests/test_fullscreen.cc
+++ b/ppapi/tests/test_fullscreen.cc
@@ -71,7 +71,7 @@ bool TestFullscreen::Init() {
instance_->AppendError("Failed to initialize graphics2d_");
return false;
}
- return InitTestingInterface();
+ return CheckTestingInterface();
}
void TestFullscreen::RunTests(const std::string& filter) {
diff --git a/ppapi/tests/test_graphics_2d.cc b/ppapi/tests/test_graphics_2d.cc
index 63cfc42..86de406 100644
--- a/ppapi/tests/test_graphics_2d.cc
+++ b/ppapi/tests/test_graphics_2d.cc
@@ -38,7 +38,7 @@ bool TestGraphics2D::Init() {
image_data_interface_ = static_cast<const PPB_ImageData*>(
pp::Module::Get()->GetBrowserInterface(PPB_IMAGEDATA_INTERFACE));
return graphics_2d_interface_ && image_data_interface_ &&
- InitTestingInterface();
+ CheckTestingInterface();
}
void TestGraphics2D::RunTests(const std::string& filter) {
diff --git a/ppapi/tests/test_graphics_3d.cc b/ppapi/tests/test_graphics_3d.cc
index 75b4d68..aa26dff 100644
--- a/ppapi/tests/test_graphics_3d.cc
+++ b/ppapi/tests/test_graphics_3d.cc
@@ -18,7 +18,7 @@ REGISTER_TEST_CASE(Graphics3D);
bool TestGraphics3D::Init() {
opengl_es2_ = static_cast<const PPB_OpenGLES2*>(
pp::Module::Get()->GetBrowserInterface(PPB_OPENGLES2_INTERFACE));
- return opengl_es2_ && InitTestingInterface();
+ return opengl_es2_ && CheckTestingInterface();
}
void TestGraphics3D::RunTests(const std::string& filter) {
diff --git a/ppapi/tests/test_input_event.cc b/ppapi/tests/test_input_event.cc
index cdd4939..8ac9a8fd 100644
--- a/ppapi/tests/test_input_event.cc
+++ b/ppapi/tests/test_input_event.cc
@@ -73,7 +73,7 @@ bool TestInputEvent::Init() {
mouse_input_event_interface_ &&
wheel_input_event_interface_ &&
keyboard_input_event_interface_ &&
- InitTestingInterface();
+ CheckTestingInterface();
// Set up a listener for our message that signals that all input events have
// been received.
diff --git a/ppapi/tests/test_memory.cc b/ppapi/tests/test_memory.cc
index 4acbd5f..ea612a4 100644
--- a/ppapi/tests/test_memory.cc
+++ b/ppapi/tests/test_memory.cc
@@ -21,7 +21,7 @@ REGISTER_TEST_CASE(Memory);
bool TestMemory::Init() {
memory_dev_interface_ = static_cast<const PPB_Memory_Dev*>(
pp::Module::Get()->GetBrowserInterface(PPB_MEMORY_DEV_INTERFACE));
- return memory_dev_interface_ && InitTestingInterface();
+ return memory_dev_interface_ && CheckTestingInterface();
}
void TestMemory::RunTests(const std::string& filter) {
diff --git a/ppapi/tests/test_post_message.cc b/ppapi/tests/test_post_message.cc
index 665dad7..6edd422 100644
--- a/ppapi/tests/test_post_message.cc
+++ b/ppapi/tests/test_post_message.cc
@@ -69,7 +69,7 @@ TestPostMessage::~TestPostMessage() {
}
bool TestPostMessage::Init() {
- bool success = InitTestingInterface();
+ bool success = CheckTestingInterface();
// Set up a special listener that only responds to a FINISHED_WAITING string.
// This is for use by WaitForMessages.
@@ -179,6 +179,7 @@ std::string TestPostMessage::TestSendInInit() {
ASSERT_EQ(message_data_.size(), 1);
ASSERT_TRUE(message_data_.back().is_string());
ASSERT_EQ(message_data_.back().AsString(), kTestString);
+ message_data_.clear();
PASS();
}
@@ -236,6 +237,7 @@ std::string TestPostMessage::TestSendingData() {
ASSERT_EQ(WaitForMessages(), 1);
ASSERT_TRUE(message_data_.back().is_null());
+ message_data_.clear();
ASSERT_TRUE(ClearListeners());
PASS();
@@ -296,6 +298,7 @@ std::string TestPostMessage::TestSendingArrayBuffer() {
for (size_t i = 0; i < test_data.ByteLength(); ++i)
ASSERT_EQ(buff[i], received_buff[i]);
+ message_data_.clear();
ASSERT_TRUE(ClearListeners());
PASS();
@@ -361,6 +364,9 @@ std::string TestPostMessage::TestMessageEvent() {
ASSERT_DOUBLE_EQ(double_vec[1], 2.0);
ASSERT_DOUBLE_EQ(double_vec[2], 3.0);
+ message_data_.clear();
+ ASSERT_TRUE(ClearListeners());
+
PASS();
}
@@ -392,6 +398,8 @@ std::string TestPostMessage::TestExtraParam() {
ASSERT_EQ(WaitForMessages(), 0);
ASSERT_TRUE(message_data_.empty());
+ ASSERT_TRUE(ClearListeners());
+
PASS();
}
@@ -448,6 +456,9 @@ std::string TestPostMessage::TestNonMainThread() {
}
ASSERT_EQ(received_counts, expected_counts);
+ message_data_.clear();
+ ASSERT_TRUE(ClearListeners());
+
PASS();
}
diff --git a/ppapi/tests/test_scrollbar.cc b/ppapi/tests/test_scrollbar.cc
index 61345d0..b005db7 100644
--- a/ppapi/tests/test_scrollbar.cc
+++ b/ppapi/tests/test_scrollbar.cc
@@ -23,7 +23,7 @@ TestScrollbar::TestScrollbar(TestingInstance* instance)
}
bool TestScrollbar::Init() {
- return InitTestingInterface();
+ return CheckTestingInterface();
}
void TestScrollbar::RunTests(const std::string& filter) {
diff --git a/ppapi/tests/test_tcp_socket_private_shared.cc b/ppapi/tests/test_tcp_socket_private_shared.cc
index 013aa89..6df6cd5 100644
--- a/ppapi/tests/test_tcp_socket_private_shared.cc
+++ b/ppapi/tests/test_tcp_socket_private_shared.cc
@@ -31,7 +31,7 @@ bool TestTCPSocketPrivateShared::Init() {
return tcp_socket_private_interface_ &&
init_host_port &&
- InitTestingInterface();
+ CheckTestingInterface();
}
void TestTCPSocketPrivateShared::RunTests(const std::string& filter) {
diff --git a/ppapi/tests/test_transport.cc b/ppapi/tests/test_transport.cc
index c5ea69c..52d072e 100644
--- a/ppapi/tests/test_transport.cc
+++ b/ppapi/tests/test_transport.cc
@@ -105,7 +105,7 @@ TestTransport::~TestTransport() {
bool TestTransport::Init() {
transport_interface_ = static_cast<const PPB_Transport_Dev*>(
pp::Module::Get()->GetBrowserInterface(PPB_TRANSPORT_DEV_INTERFACE));
- return transport_interface_ && InitTestingInterface();
+ return transport_interface_ && CheckTestingInterface();
}
void TestTransport::RunTests(const std::string& filter) {
diff --git a/ppapi/tests/test_udp_socket_private_shared.cc b/ppapi/tests/test_udp_socket_private_shared.cc
index da97cae..2de64778 100644
--- a/ppapi/tests/test_udp_socket_private_shared.cc
+++ b/ppapi/tests/test_udp_socket_private_shared.cc
@@ -38,7 +38,7 @@ bool TestUDPSocketPrivateShared::Init() {
return tcp_socket_private_interface_ &&
udp_socket_private_interface_ &&
init_host_port &&
- InitTestingInterface();
+ CheckTestingInterface();
}
void TestUDPSocketPrivateShared::RunTests(const std::string& filter) {
diff --git a/ppapi/tests/test_url_loader.cc b/ppapi/tests/test_url_loader.cc
index 630d00f..741d415 100644
--- a/ppapi/tests/test_url_loader.cc
+++ b/ppapi/tests/test_url_loader.cc
@@ -63,7 +63,7 @@ TestURLLoader::TestURLLoader(TestingInstance* instance)
}
bool TestURLLoader::Init() {
- if (!InitTestingInterface()) {
+ if (!CheckTestingInterface()) {
instance_->AppendError("Testing interface not available");
return false;
}
diff --git a/ppapi/tests/test_var.cc b/ppapi/tests/test_var.cc
index 27c4882..0fedb13 100644
--- a/ppapi/tests/test_var.cc
+++ b/ppapi/tests/test_var.cc
@@ -27,7 +27,7 @@ REGISTER_TEST_CASE(Var);
bool TestVar::Init() {
var_interface_ = static_cast<const PPB_Var*>(
pp::Module::Get()->GetBrowserInterface(PPB_VAR_INTERFACE));
- return var_interface_ && InitTestingInterface();
+ return var_interface_ && CheckTestingInterface();
}
void TestVar::RunTests(const std::string& filter) {
@@ -136,6 +136,7 @@ std::string TestVar::TestNullInputInUtf8Conversion() {
if (result == NULL) {
return "Expected a non-null result for 0-lengthed string from VarToUtf8.";
}
+ var_interface_->Release(converted_string);
// Should not crash, and make an empty string.
const char* null_string = NULL;
diff --git a/ppapi/tests/test_var_deprecated.cc b/ppapi/tests/test_var_deprecated.cc
index 00585e6..23633ac 100644
--- a/ppapi/tests/test_var_deprecated.cc
+++ b/ppapi/tests/test_var_deprecated.cc
@@ -69,7 +69,7 @@ REGISTER_TEST_CASE(VarDeprecated);
bool TestVarDeprecated::Init() {
var_interface_ = static_cast<const PPB_Var_Deprecated*>(
pp::Module::Get()->GetBrowserInterface(PPB_VAR_DEPRECATED_INTERFACE));
- return var_interface_ && InitTestingInterface();
+ return var_interface_ && CheckTestingInterface();
}
void TestVarDeprecated::RunTests(const std::string& filter) {
@@ -179,6 +179,7 @@ std::string TestVarDeprecated::TestNullInputInUtf8Conversion() {
if (result == NULL) {
return "Expected a non-null result for 0-lengthed string from VarToUtf8.";
}
+ var_interface_->Release(converted_string);
// Should not crash, and make an empty string.
const char* null_string = NULL;
@@ -386,6 +387,10 @@ std::string TestVarDeprecated::TestPassReference() {
ASSERT_TRUE(result.is_string());
ASSERT_TRUE(result.AsString() == "worksnice");
+ // Reset var_from_page_ so it doesn't seem like a leak to the var leak
+ // checking code.
+ var_from_page_ = pp::Var();
+
PASS();
}
diff --git a/ppapi/tests/test_video_decoder.cc b/ppapi/tests/test_video_decoder.cc
index eed14d8..0cee794 100644
--- a/ppapi/tests/test_video_decoder.cc
+++ b/ppapi/tests/test_video_decoder.cc
@@ -15,7 +15,7 @@ REGISTER_TEST_CASE(VideoDecoder);
bool TestVideoDecoder::Init() {
video_decoder_interface_ = static_cast<const PPB_VideoDecoder_Dev*>(
pp::Module::Get()->GetBrowserInterface(PPB_VIDEODECODER_DEV_INTERFACE));
- return video_decoder_interface_ && InitTestingInterface();
+ return video_decoder_interface_ && CheckTestingInterface();
}
void TestVideoDecoder::RunTests(const std::string& filter) {
diff --git a/ppapi/tests/test_websocket.cc b/ppapi/tests/test_websocket.cc
index ae1db54..223331e 100644
--- a/ppapi/tests/test_websocket.cc
+++ b/ppapi/tests/test_websocket.cc
@@ -53,7 +53,7 @@ bool TestWebSocket::Init() {
if (!websocket_interface_ || !var_interface_ || !core_interface_)
return false;
- return InitTestingInterface();
+ return CheckTestingInterface();
}
void TestWebSocket::RunTests(const std::string& filter) {
diff --git a/webkit/plugins/ppapi/message_channel.cc b/webkit/plugins/ppapi/message_channel.cc
index a6fafae..7eef69e 100644
--- a/webkit/plugins/ppapi/message_channel.cc
+++ b/webkit/plugins/ppapi/message_channel.cc
@@ -184,6 +184,7 @@ bool MessageChannelInvoke(NPObject* np_obj, NPIdentifier name,
MessageChannel& message_channel(ToMessageChannel(np_obj));
PP_Var argument(NPVariantToPPVar(message_channel.instance(), &args[0]));
message_channel.PostMessageToNative(argument);
+ PpapiGlobals::Get()->GetVarTracker()->ReleaseVar(argument);
return true;
}
// Other method calls we will pass to the passthrough object, if we have one.
diff --git a/webkit/plugins/ppapi/plugin_module.cc b/webkit/plugins/ppapi/plugin_module.cc
index 3cb4c482..9934666 100644
--- a/webkit/plugins/ppapi/plugin_module.cc
+++ b/webkit/plugins/ppapi/plugin_module.cc
@@ -247,6 +247,16 @@ PP_Var GetDocumentURL(PP_Instance instance, PP_URLComponents_Dev* components) {
return plugin_instance->GetDocumentURL(instance, components);
}
+uint32_t GetLiveVars(PP_Var live_vars[], uint32_t array_size) {
+ std::vector<PP_Var> vars =
+ PpapiGlobals::Get()->GetVarTracker()->GetLiveVars();
+ for (size_t i = 0u;
+ i < std::min(static_cast<size_t>(array_size), vars.size());
+ ++i)
+ live_vars[i] = vars[i];
+ return vars.size();
+}
+
const PPB_Testing_Dev testing_interface = {
&ReadImageData,
&RunMessageLoop,
@@ -254,7 +264,8 @@ const PPB_Testing_Dev testing_interface = {
&GetLiveObjectsForInstance,
&IsOutOfProcess,
&SimulateInputEvent,
- &GetDocumentURL
+ &GetDocumentURL,
+ &GetLiveVars
};
// GetInterface ----------------------------------------------------------------
@@ -351,8 +362,7 @@ const void* GetInterface(const char* name) {
if (CommandLine::ForCurrentProcess()->HasSwitch(
switches::kEnablePepperTesting)) {
if (strcmp(name, PPB_TESTING_DEV_INTERFACE) == 0 ||
- strcmp(name, PPB_TESTING_DEV_INTERFACE_0_7) == 0 ||
- strcmp(name, PPB_TESTING_DEV_INTERFACE_0_8) == 0) {
+ strcmp(name, PPB_TESTING_DEV_INTERFACE_0_9) == 0) {
return &testing_interface;
}
}