#include <stdint.h>
#include "base/functional/bind.h"
#include "base/test/test_timeouts.h"
#include "base/time/time.h"
#include "ppapi/c/dev/ppb_var_deprecated.h"
#include "ppapi/c/dev/ppp_class_deprecated.h"
#include "ppapi/c/pp_var.h"
#include "ppapi/c/ppb_var.h"
#include "ppapi/c/ppp_instance.h"
#include "ppapi/c/private/ppp_instance_private.h"
#include "ppapi/proxy/host_dispatcher.h"
#include "ppapi/proxy/interface_list.h"
#include "ppapi/proxy/ppapi_proxy_test.h"
#include "ppapi/shared_impl/ppapi_permissions.h"
#include "ppapi/shared_impl/ppb_var_shared.h"
#include "ppapi/shared_impl/var.h"
namespace ppapi {
class V8ObjectVar : public ppapi::Var {
public:
V8ObjectVar(const PPP_Class_Deprecated* ppp_class, void* ppp_class_data)
: ppp_class_(ppp_class), ppp_class_data_(ppp_class_data) {}
~V8ObjectVar() override { ppp_class_->Deallocate(ppp_class_data_); }
V8ObjectVar* AsV8ObjectVar() override { return this; }
PP_VarType GetType() const override { return PP_VARTYPE_OBJECT; }
private:
const PPP_Class_Deprecated* ppp_class_;
void* ppp_class_data_;
};
namespace proxy {
namespace {
const PP_Instance kInstance = 0xdeadbeef;
PP_Var GetPPVarNoAddRef(Var* var) {
PP_Var var_to_return = var->GetPPVar();
PpapiGlobals::Get()->GetVarTracker()->ReleaseVar(var_to_return);
return var_to_return;
}
PluginDispatcher* plugin_dispatcher = NULL;
const PPB_Var_Deprecated* plugin_var_deprecated_if() {
CHECK(plugin_dispatcher);
return static_cast<const PPB_Var_Deprecated*>(
plugin_dispatcher->GetBrowserInterface(
PPB_VAR_DEPRECATED_INTERFACE));
}
PP_Var instance_obj;
PP_Var GetInstanceObject(PP_Instance ) {
printf("GetInstanceObject called\n");
plugin_var_deprecated_if()->AddRef(instance_obj);
return instance_obj;
}
PPP_Instance_Private ppp_instance_private_mock = {
&GetInstanceObject
};
void Deallocate(void* object) {
}
const PPP_Class_Deprecated ppp_class_deprecated_mock = {
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
&Deallocate
};
PP_Bool DidCreate(PP_Instance , uint32_t ,
const char* [], const char* []) {
instance_obj =
plugin_var_deprecated_if()->CreateObject(kInstance,
&ppp_class_deprecated_mock,
NULL);
return PP_TRUE;
}
void DidDestroy(PP_Instance ) {
plugin_var_deprecated_if()->Release(instance_obj);
}
PPP_Instance_1_0 ppp_instance_mock = { &DidCreate, &DidDestroy };
PP_Var CreateObject(PP_Instance ,
const PPP_Class_Deprecated* ppp_class,
void* ppp_class_data) {
V8ObjectVar* obj_var = new V8ObjectVar(ppp_class, ppp_class_data);
return obj_var->GetPPVar();
}
const PPB_Var_Deprecated ppb_var_deprecated_mock = {
PPB_Var_Shared::GetVarInterface1_0()->AddRef,
PPB_Var_Shared::GetVarInterface1_0()->Release,
PPB_Var_Shared::GetVarInterface1_0()->VarFromUtf8,
PPB_Var_Shared::GetVarInterface1_0()->VarToUtf8,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
&CreateObject
};
class PPP_Instance_Private_ProxyTest : public TwoWayTest {
public:
PPP_Instance_Private_ProxyTest()
: TwoWayTest(TwoWayTest::TEST_PPP_INTERFACE) {
plugin().RegisterTestInterface(PPP_INSTANCE_PRIVATE_INTERFACE,
&ppp_instance_private_mock);
plugin().RegisterTestInterface(PPP_INSTANCE_INTERFACE_1_0,
&ppp_instance_mock);
host().RegisterTestInterface(PPB_VAR_DEPRECATED_INTERFACE,
&ppb_var_deprecated_mock);
}
};
}
TEST_F(PPP_Instance_Private_ProxyTest, PPPInstancePrivate) {
ASSERT_NE(kInstance, pp_instance());
HostDispatcher::SetForInstance(kInstance, host().host_dispatcher());
InterfaceList::SetProcessGlobalPermissions(
PpapiPermissions::AllPermissions());
plugin_dispatcher = plugin().plugin_dispatcher();
const PPP_Instance_Private* ppp_instance_private =
static_cast<const PPP_Instance_Private*>(
host().host_dispatcher()->GetProxiedInterface(
PPP_INSTANCE_PRIVATE_INTERFACE));
const PPP_Instance_1_1* ppp_instance = static_cast<const PPP_Instance_1_1*>(
host().host_dispatcher()->GetProxiedInterface(
PPP_INSTANCE_INTERFACE_1_1));
EXPECT_EQ(PP_TRUE, ppp_instance->DidCreate(kInstance, 0, NULL, NULL));
EXPECT_EQ(1, plugin().var_tracker().GetRefCountForObject(instance_obj));
int32_t expected_host_id =
plugin().var_tracker().GetHostObject(instance_obj).value.as_id;
Var* host_var = host().var_tracker().GetVar(expected_host_id);
ASSERT_TRUE(host_var);
EXPECT_EQ(
1,
host().var_tracker().GetRefCountForObject(GetPPVarNoAddRef(host_var)));
PP_Var host_pp_var = ppp_instance_private->GetInstanceObject(kInstance);
EXPECT_EQ(instance_obj.type, host_pp_var.type);
EXPECT_EQ(host_pp_var.value.as_id, expected_host_id);
EXPECT_EQ(1, plugin().var_tracker().GetRefCountForObject(instance_obj));
host().var_tracker().ReleaseVar(host_pp_var);
EXPECT_EQ(1, host().var_tracker().GetRefCountForObject(host_pp_var));
host().var_tracker().ReleaseVar(host_pp_var);
ppp_instance->DidDestroy(kInstance);
EXPECT_EQ(-1, plugin().var_tracker().GetRefCountForObject(instance_obj));
EXPECT_EQ(-1, host().var_tracker().GetRefCountForObject(host_pp_var));
}
}
}