This source file includes following definitions.
- MakeObject
- MarkOnDeallocate
- GetObjectIDForUniqueReleaseObject
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
#include "ipc/ipc_test_sink.h"
#include "ppapi/c/dev/ppp_class_deprecated.h"
#include "ppapi/proxy/plugin_var_tracker.h"
#include "ppapi/proxy/ppapi_messages.h"
#include "ppapi/proxy/ppapi_proxy_test.h"
#include "ppapi/proxy/proxy_object_var.h"
#include "ppapi/shared_impl/proxy_lock.h"
namespace ppapi {
namespace proxy {
namespace {
PP_Var MakeObject(int32 object_id) {
PP_Var ret;
ret.type = PP_VARTYPE_OBJECT;
ret.value.as_id = object_id;
return ret;
}
void MarkOnDeallocate(void* object) {
(*static_cast<int*>(object))++;
}
PPP_Class_Deprecated mark_on_deallocate_class = {
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
&MarkOnDeallocate
};
}
class PluginVarTrackerTest : public PluginProxyTest {
public:
PluginVarTrackerTest() {}
protected:
int32 GetObjectIDForUniqueReleaseObject() {
const IPC::Message* release_msg = sink().GetUniqueMessageMatching(
PpapiHostMsg_PPBVar_ReleaseObject::ID);
if (!release_msg)
return -1;
Tuple1<int64> id;
PpapiHostMsg_PPBVar_ReleaseObject::Read(release_msg, &id);
return id.a;
}
};
TEST_F(PluginVarTrackerTest, GetHostObject) {
ProxyAutoLock lock;
PP_Var host_object = MakeObject(12345);
PP_Var plugin_object = var_tracker().ReceiveObjectPassRef(
host_object, plugin_dispatcher());
PP_Var host_object2 = var_tracker().GetHostObject(plugin_object);
EXPECT_EQ(PP_VARTYPE_OBJECT, host_object2.type);
EXPECT_EQ(host_object.value.as_id, host_object2.value.as_id);
var_tracker().ReleaseVar(plugin_object);
}
TEST_F(PluginVarTrackerTest, ReceiveObjectPassRef) {
ProxyAutoLock lock;
PP_Var host_object = MakeObject(12345);
PP_Var plugin_object = var_tracker().ReceiveObjectPassRef(
host_object, plugin_dispatcher());
EXPECT_EQ(0u, sink().message_count());
EXPECT_EQ(1, var_tracker().GetRefCountForObject(plugin_object));
EXPECT_EQ(0,
var_tracker().GetTrackedWithNoReferenceCountForObject(plugin_object));
PP_Var plugin_object2 = var_tracker().ReceiveObjectPassRef(
host_object, plugin_dispatcher());
EXPECT_EQ(plugin_object.value.as_id, plugin_object2.value.as_id);
EXPECT_EQ(2, var_tracker().GetRefCountForObject(plugin_object));
EXPECT_EQ(0,
var_tracker().GetTrackedWithNoReferenceCountForObject(plugin_object));
EXPECT_EQ(host_object.value.as_id, GetObjectIDForUniqueReleaseObject());
sink().ClearMessages();
var_tracker().ReleaseVar(plugin_object);
EXPECT_EQ(1, var_tracker().GetRefCountForObject(plugin_object));
var_tracker().ReleaseVar(plugin_object);
EXPECT_EQ(-1, var_tracker().GetRefCountForObject(plugin_object));
EXPECT_EQ(host_object.value.as_id, GetObjectIDForUniqueReleaseObject());
}
TEST_F(PluginVarTrackerTest, FreeTrackedAndReferencedObject) {
ProxyAutoLock lock;
PP_Var host_object = MakeObject(12345);
PP_Var plugin_var = var_tracker().ReceiveObjectPassRef(
host_object, plugin_dispatcher());
PP_Var plugin_var2 = var_tracker().TrackObjectWithNoReference(
host_object, plugin_dispatcher());
EXPECT_EQ(plugin_var.value.as_id, plugin_var2.value.as_id);
EXPECT_EQ(1, var_tracker().GetRefCountForObject(plugin_var));
EXPECT_EQ(1,
var_tracker().GetTrackedWithNoReferenceCountForObject(plugin_var));
var_tracker().ReleaseVar(plugin_var);
EXPECT_EQ(0, var_tracker().GetRefCountForObject(plugin_var));
EXPECT_EQ(1u, sink().message_count());
EXPECT_EQ(host_object.value.as_id, GetObjectIDForUniqueReleaseObject());
var_tracker().StopTrackingObjectWithNoReference(plugin_var);
EXPECT_EQ(-1, var_tracker().GetRefCountForObject(plugin_var));
sink().ClearMessages();
plugin_var = var_tracker().TrackObjectWithNoReference(
host_object, plugin_dispatcher());
plugin_var2 = var_tracker().ReceiveObjectPassRef(
host_object, plugin_dispatcher());
EXPECT_EQ(plugin_var.value.as_id, plugin_var2.value.as_id);
EXPECT_EQ(1, var_tracker().GetRefCountForObject(plugin_var));
EXPECT_EQ(1,
var_tracker().GetTrackedWithNoReferenceCountForObject(plugin_var));
var_tracker().StopTrackingObjectWithNoReference(plugin_var);
EXPECT_EQ(0,
var_tracker().GetTrackedWithNoReferenceCountForObject(plugin_var));
EXPECT_EQ(0u, sink().message_count());
var_tracker().ReleaseVar(plugin_var);
EXPECT_EQ(-1, var_tracker().GetRefCountForObject(plugin_var));
EXPECT_EQ(host_object.value.as_id, GetObjectIDForUniqueReleaseObject());
}
TEST_F(PluginVarTrackerTest, RecursiveTrackWithNoRef) {
ProxyAutoLock lock;
PP_Var host_object = MakeObject(12345);
PP_Var plugin_var = var_tracker().TrackObjectWithNoReference(
host_object, plugin_dispatcher());
EXPECT_EQ(1,
var_tracker().GetTrackedWithNoReferenceCountForObject(plugin_var));
PP_Var plugin_var2 = var_tracker().TrackObjectWithNoReference(
host_object, plugin_dispatcher());
EXPECT_EQ(plugin_var.value.as_id, plugin_var2.value.as_id);
EXPECT_EQ(0, var_tracker().GetRefCountForObject(plugin_var));
EXPECT_EQ(2,
var_tracker().GetTrackedWithNoReferenceCountForObject(plugin_var));
var_tracker().StopTrackingObjectWithNoReference(plugin_var);
EXPECT_EQ(1,
var_tracker().GetTrackedWithNoReferenceCountForObject(plugin_var));
var_tracker().StopTrackingObjectWithNoReference(plugin_var);
EXPECT_EQ(-1,
var_tracker().GetTrackedWithNoReferenceCountForObject(plugin_var));
}
TEST_F(PluginVarTrackerTest, PluginObjectInstanceDeleted) {
ProxyAutoLock lock;
PP_Var host_object = MakeObject(12345);
PP_Instance pp_instance = 0x12345;
int deallocate_called = 0;
void* user_data = &deallocate_called;
scoped_refptr<ProxyObjectVar> object(
new ProxyObjectVar(plugin_dispatcher(), host_object.value.as_id));
PP_Var plugin_var = MakeObject(var_tracker().AddVar(object.get()));
var_tracker().PluginImplementedObjectCreated(
pp_instance, plugin_var, &mark_on_deallocate_class, user_data);
object = NULL;
var_tracker().ReleaseVar(plugin_var);
EXPECT_EQ(0, deallocate_called);
var_tracker().DidDeleteInstance(pp_instance);
EXPECT_EQ(1, deallocate_called);
}
TEST_F(PluginVarTrackerTest, PluginObjectLeaked) {
ProxyAutoLock lock;
PP_Var host_object = MakeObject(12345);
PP_Instance pp_instance = 0x12345;
int deallocate_called = 0;
void* user_data = &deallocate_called;
scoped_refptr<ProxyObjectVar> object(
new ProxyObjectVar(plugin_dispatcher(), host_object.value.as_id));
PP_Var plugin_var = MakeObject(var_tracker().AddVar(object.get()));
var_tracker().PluginImplementedObjectCreated(
pp_instance, plugin_var, &mark_on_deallocate_class, user_data);
var_tracker().DidDeleteInstance(pp_instance);
EXPECT_EQ(0, deallocate_called);
object = NULL;
var_tracker().ReleaseVar(plugin_var);
EXPECT_EQ(1, deallocate_called);
}
}
}