This source file includes following definitions.
- pp_instance
- SetUp
- TearDown
- TestCallback
- info_did_run
- info_did_abort
- info_didnt_run
- TEST_F
- SetupForTest
- CompletionTask
- CheckIntermediateState
- CheckFinalState
- TEST_F
- TEST_F
#include "base/bind.h"
#include "base/memory/ref_counted.h"
#include "base/message_loop/message_loop.h"
#include "ppapi/c/pp_completion_callback.h"
#include "ppapi/c/pp_errors.h"
#include "ppapi/shared_impl/callback_tracker.h"
#include "ppapi/shared_impl/proxy_lock.h"
#include "ppapi/shared_impl/resource.h"
#include "ppapi/shared_impl/resource_tracker.h"
#include "ppapi/shared_impl/test_globals.h"
#include "ppapi/shared_impl/tracked_callback.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace ppapi {
namespace {
class TrackedCallbackTest : public testing::Test {
public:
TrackedCallbackTest() : pp_instance_(1234) {}
PP_Instance pp_instance() const { return pp_instance_; }
virtual void SetUp() OVERRIDE {
ProxyLock::EnableLockingOnThreadForTest();
ProxyAutoLock lock;
globals_.GetResourceTracker()->DidCreateInstance(pp_instance_);
}
virtual void TearDown() OVERRIDE {
ProxyAutoLock lock;
globals_.GetResourceTracker()->DidDeleteInstance(pp_instance_);
}
private:
base::MessageLoop message_loop_;
TestGlobals globals_;
PP_Instance pp_instance_;
};
const int32_t kInitializedResultValue = 1;
const int32_t kOverrideResultValue = 2;
struct CallbackRunInfo {
CallbackRunInfo()
: run_count(0),
result(kInitializedResultValue),
completion_task_run_count(0),
completion_task_result(kInitializedResultValue) {}
unsigned run_count;
int32_t result;
unsigned completion_task_run_count;
int32_t completion_task_result;
};
void TestCallback(void* user_data, int32_t result) {
CallbackRunInfo* info = reinterpret_cast<CallbackRunInfo*>(user_data);
info->run_count++;
if (info->run_count == 1)
info->result = result;
}
}
namespace {
class CallbackShutdownTest : public TrackedCallbackTest {
public:
CallbackShutdownTest() {}
CallbackRunInfo& info_did_run() { return info_did_run_; }
CallbackRunInfo& info_did_abort() { return info_did_abort_; }
CallbackRunInfo& info_didnt_run() { return info_didnt_run_; }
private:
CallbackRunInfo info_did_run_;
CallbackRunInfo info_did_abort_;
CallbackRunInfo info_didnt_run_;
};
}
TEST_F(CallbackShutdownTest, AbortOnShutdown) {
ProxyAutoLock lock;
scoped_refptr<Resource> resource(new Resource(OBJECT_IS_IMPL, pp_instance()));
EXPECT_EQ(0U, info_did_run().run_count);
scoped_refptr<TrackedCallback> callback_did_run = new TrackedCallback(
resource.get(),
PP_MakeCompletionCallback(&TestCallback, &info_did_run()));
EXPECT_EQ(0U, info_did_run().run_count);
callback_did_run->Run(PP_OK);
EXPECT_EQ(1U, info_did_run().run_count);
EXPECT_EQ(PP_OK, info_did_run().result);
EXPECT_EQ(0U, info_did_abort().run_count);
scoped_refptr<TrackedCallback> callback_did_abort = new TrackedCallback(
resource.get(),
PP_MakeCompletionCallback(&TestCallback, &info_did_abort()));
EXPECT_EQ(0U, info_did_abort().run_count);
callback_did_abort->Abort();
EXPECT_EQ(1U, info_did_abort().run_count);
EXPECT_EQ(PP_ERROR_ABORTED, info_did_abort().result);
EXPECT_EQ(0U, info_didnt_run().run_count);
scoped_refptr<TrackedCallback> callback_didnt_run = new TrackedCallback(
resource.get(),
PP_MakeCompletionCallback(&TestCallback, &info_didnt_run()));
EXPECT_EQ(0U, info_didnt_run().run_count);
PpapiGlobals::Get()->GetCallbackTrackerForInstance(pp_instance())->AbortAll();
EXPECT_EQ(1U, info_did_run().run_count);
EXPECT_EQ(1U, info_did_abort().run_count);
EXPECT_EQ(1U, info_didnt_run().run_count);
EXPECT_EQ(PP_ERROR_ABORTED, info_didnt_run().result);
}
namespace {
class CallbackResourceTest : public TrackedCallbackTest {
public:
CallbackResourceTest() {}
};
class CallbackMockResource : public Resource {
public:
CallbackMockResource(PP_Instance instance)
: Resource(OBJECT_IS_IMPL, instance) {}
~CallbackMockResource() {}
PP_Resource SetupForTest() {
PP_Resource resource_id = GetReference();
EXPECT_NE(0, resource_id);
callback_did_run_ = new TrackedCallback(
this, PP_MakeCompletionCallback(&TestCallback, &info_did_run_));
EXPECT_EQ(0U, info_did_run_.run_count);
EXPECT_EQ(0U, info_did_run_.completion_task_run_count);
callback_did_run_with_completion_task_ = new TrackedCallback(
this,
PP_MakeCompletionCallback(&TestCallback,
&info_did_run_with_completion_task_));
callback_did_run_with_completion_task_->set_completion_task(
Bind(&CallbackMockResource::CompletionTask,
this,
&info_did_run_with_completion_task_));
EXPECT_EQ(0U, info_did_run_with_completion_task_.run_count);
EXPECT_EQ(0U, info_did_run_with_completion_task_.completion_task_run_count);
callback_did_abort_ = new TrackedCallback(
this, PP_MakeCompletionCallback(&TestCallback, &info_did_abort_));
callback_did_abort_->set_completion_task(
Bind(&CallbackMockResource::CompletionTask, this, &info_did_abort_));
EXPECT_EQ(0U, info_did_abort_.run_count);
EXPECT_EQ(0U, info_did_abort_.completion_task_run_count);
callback_didnt_run_ = new TrackedCallback(
this, PP_MakeCompletionCallback(&TestCallback, &info_didnt_run_));
callback_didnt_run_->set_completion_task(
Bind(&CallbackMockResource::CompletionTask, this, &info_didnt_run_));
EXPECT_EQ(0U, info_didnt_run_.run_count);
EXPECT_EQ(0U, info_didnt_run_.completion_task_run_count);
callback_did_run_->Run(PP_OK);
callback_did_run_with_completion_task_->Run(PP_OK);
callback_did_abort_->Abort();
CheckIntermediateState();
return resource_id;
}
int32_t CompletionTask(CallbackRunInfo* info, int32_t result) {
EXPECT_EQ(0U, info->run_count);
info->completion_task_run_count++;
if (info->completion_task_run_count == 1)
info->completion_task_result = result;
return kOverrideResultValue;
}
void CheckIntermediateState() {
EXPECT_EQ(1U, info_did_run_.run_count);
EXPECT_EQ(PP_OK, info_did_run_.result);
EXPECT_EQ(0U, info_did_run_.completion_task_run_count);
EXPECT_EQ(1U, info_did_run_with_completion_task_.run_count);
EXPECT_EQ(kOverrideResultValue, info_did_run_with_completion_task_.result);
EXPECT_EQ(1U, info_did_run_with_completion_task_.completion_task_run_count);
EXPECT_EQ(PP_OK, info_did_run_with_completion_task_.completion_task_result);
EXPECT_EQ(1U, info_did_abort_.run_count);
EXPECT_EQ(PP_ERROR_ABORTED, info_did_abort_.result);
EXPECT_EQ(1U, info_did_abort_.completion_task_run_count);
EXPECT_EQ(PP_ERROR_ABORTED, info_did_abort_.completion_task_result);
EXPECT_EQ(0U, info_didnt_run_.completion_task_run_count);
EXPECT_EQ(0U, info_didnt_run_.run_count);
}
void CheckFinalState() {
EXPECT_EQ(1U, info_did_run_.run_count);
EXPECT_EQ(PP_OK, info_did_run_.result);
EXPECT_EQ(1U, info_did_abort_.run_count);
EXPECT_EQ(PP_ERROR_ABORTED, info_did_abort_.result);
EXPECT_EQ(1U, info_didnt_run_.run_count);
EXPECT_EQ(PP_ERROR_ABORTED, info_didnt_run_.result);
}
scoped_refptr<TrackedCallback> callback_did_run_;
CallbackRunInfo info_did_run_;
scoped_refptr<TrackedCallback> callback_did_run_with_completion_task_;
CallbackRunInfo info_did_run_with_completion_task_;
scoped_refptr<TrackedCallback> callback_did_abort_;
CallbackRunInfo info_did_abort_;
scoped_refptr<TrackedCallback> callback_didnt_run_;
CallbackRunInfo info_didnt_run_;
};
}
TEST_F(CallbackResourceTest, AbortOnNoRef) {
ProxyAutoLock lock;
ResourceTracker* resource_tracker = PpapiGlobals::Get()->GetResourceTracker();
scoped_refptr<CallbackMockResource> resource_1(
new CallbackMockResource(pp_instance()));
PP_Resource resource_1_id = resource_1->SetupForTest();
scoped_refptr<CallbackMockResource> resource_2(
new CallbackMockResource(pp_instance()));
PP_Resource resource_2_id = resource_2->SetupForTest();
resource_1->CheckIntermediateState();
resource_tracker->ReleaseResource(resource_1_id);
{
ProxyAutoUnlock unlock;
base::MessageLoop::current()->RunUntilIdle();
}
resource_1->CheckFinalState();
resource_2->CheckIntermediateState();
resource_tracker->ReleaseResource(resource_2_id);
{
ProxyAutoUnlock unlock;
base::MessageLoop::current()->RunUntilIdle();
}
resource_1->CheckFinalState();
resource_2->CheckFinalState();
{
ProxyAutoUnlock unlock;
base::MessageLoop::current()->RunUntilIdle();
}
}
TEST_F(CallbackResourceTest, Resurrection) {
ProxyAutoLock lock;
ResourceTracker* resource_tracker = PpapiGlobals::Get()->GetResourceTracker();
scoped_refptr<CallbackMockResource> resource(
new CallbackMockResource(pp_instance()));
PP_Resource resource_id = resource->SetupForTest();
resource_tracker->ReleaseResource(resource_id);
{
ProxyAutoUnlock unlock;
base::MessageLoop::current()->RunUntilIdle();
}
resource->CheckFinalState();
PP_Resource new_resource_id = resource->GetReference();
{
ProxyAutoUnlock unlock;
base::MessageLoop::current()->RunUntilIdle();
}
resource->CheckFinalState();
resource_tracker->ReleaseResource(new_resource_id);
{
ProxyAutoUnlock unlock;
base::MessageLoop::current()->RunUntilIdle();
}
resource->CheckFinalState();
{
ProxyAutoUnlock unlock;
base::MessageLoop::current()->RunUntilIdle();
}
}
}