// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <GLES2/gl2.h>

#include "base/memory/shared_memory.h"
#include "base/message_loop/message_loop.h"
#include "ppapi/c/pp_errors.h"
#include "ppapi/c/ppb_video_decoder.h"
#include "ppapi/proxy/locking_resource_releaser.h"
#include "ppapi/proxy/plugin_message_filter.h"
#include "ppapi/proxy/ppapi_message_utils.h"
#include "ppapi/proxy/ppapi_messages.h"
#include "ppapi/proxy/ppapi_proxy_test.h"
#include "ppapi/proxy/ppb_graphics_3d_proxy.h"
#include "ppapi/proxy/video_decoder_constants.h"
#include "ppapi/proxy/video_decoder_resource.h"
#include "ppapi/shared_impl/proxy_lock.h"
#include "ppapi/thunk/thunk.h"

using ppapi::proxy::ResourceMessageTestSink;

namespace ppapi {
namespace proxy {

namespace {

const PP_Resource kGraphics3D = 7;
const uint32_t kShmSize = 256;
const size_t kDecodeBufferSize = 16;
const uint32_t kDecodeId = 5;
const uint32_t kTextureId1 = 1;
const uint32_t kTextureId2 = 2;
const uint32_t kNumRequestedTextures = 2;

class MockCompletionCallback {
 public:
  MockCompletionCallback() : called_(false) {}

  bool called() { return called_; }
  int32_t result() { return result_; }

  void Reset() { called_ = false; }

  static void Callback(void* user_data, int32_t result) {
    MockCompletionCallback* that =
        reinterpret_cast<MockCompletionCallback*>(user_data);
    that->called_ = true;
    that->result_ = result;
  }

 private:
  bool called_;
  int32_t result_;
};

class VideoDecoderResourceTest : public PluginProxyTest {
 public:
  VideoDecoderResourceTest()
      : decoder_iface_(thunk::GetPPB_VideoDecoder_0_2_Thunk()) {}

  const PPB_VideoDecoder_0_2* decoder_iface() const { return decoder_iface_; }

  void SendReply(const ResourceMessageCallParams& params,
                 int32_t result,
                 const IPC::Message& nested_message) {
    ResourceMessageReplyParams reply_params(params.pp_resource(),
                                            params.sequence());
    reply_params.set_result(result);
    PluginMessageFilter::DispatchResourceReplyForTest(reply_params,
                                                      nested_message);
  }

  void SendReplyWithHandle(const ResourceMessageCallParams& params,
                           int32_t result,
                           const IPC::Message& nested_message,
                           const SerializedHandle& handle) {
    ResourceMessageReplyParams reply_params(params.pp_resource(),
                                            params.sequence());
    reply_params.set_result(result);
    reply_params.AppendHandle(handle);
    PluginMessageFilter::DispatchResourceReplyForTest(reply_params,
                                                      nested_message);
  }

  PP_Resource CreateDecoder() {
    PP_Resource result = decoder_iface()->Create(pp_instance());
    if (result) {
      ProxyAutoLock lock;
      ppapi::Resource* resource =
          GetGlobals()->GetResourceTracker()->GetResource(result);
      proxy::VideoDecoderResource* decoder =
          static_cast<proxy::VideoDecoderResource*>(resource);
      decoder->SetForTest();
    }

    return result;
  }

  PP_Resource CreateGraphics3d() {
    ProxyAutoLock lock;

    HostResource host_resource;
    host_resource.SetHostResource(pp_instance(), kGraphics3D);
    scoped_refptr<ppapi::proxy::Graphics3D> graphics_3d(
        new ppapi::proxy::Graphics3D(host_resource));
    return graphics_3d->GetReference();
  }

  PP_Resource CreateAndInitializeDecoder() {
    PP_Resource decoder = CreateDecoder();
    LockingResourceReleaser graphics3d(CreateGraphics3d());
    MockCompletionCallback cb;
    int32_t result = decoder_iface()->Initialize(
        decoder,
        graphics3d.get(),
        PP_VIDEOPROFILE_H264MAIN,
        PP_HARDWAREACCELERATION_WITHFALLBACK,
        PP_MakeOptionalCompletionCallback(&MockCompletionCallback::Callback,
                                          &cb));
    if (result != PP_OK_COMPLETIONPENDING)
      return 0;
    ResourceMessageCallParams params;
    IPC::Message msg;
    if (!sink().GetFirstResourceCallMatching(
            PpapiHostMsg_VideoDecoder_Initialize::ID, &params, &msg))
      return 0;
    sink().ClearMessages();
    SendReply(params, PP_OK, PpapiPluginMsg_VideoDecoder_InitializeReply());
    return decoder;
  }

  int32_t CallDecode(PP_Resource pp_decoder,
                     MockCompletionCallback* cb,
                     const PpapiHostMsg_VideoDecoder_GetShm* expected_shm_msg) {
    // Set up a handler in case the resource sends a sync message to create
    // shared memory.
    PpapiPluginMsg_VideoDecoder_GetShmReply shm_msg_reply(kShmSize);
    ResourceSyncCallHandler shm_msg_handler(
        &sink(), PpapiHostMsg_VideoDecoder_GetShm::ID, PP_OK, shm_msg_reply);
    sink().AddFilter(&shm_msg_handler);

    base::SharedMemory shm;
    if (expected_shm_msg) {
      shm.CreateAnonymous(kShmSize);
      base::SharedMemoryHandle shm_handle;
      shm.ShareToProcess(base::GetCurrentProcessHandle(), &shm_handle);
      SerializedHandle serialized_handle(shm_handle, kShmSize);
      shm_msg_handler.set_serialized_handle(&serialized_handle);
    }

    memset(decode_buffer_, 0x55, kDecodeBufferSize);
    int32_t result =
        decoder_iface()->Decode(pp_decoder,
                                kDecodeId,
                                kDecodeBufferSize,
                                decode_buffer_,
                                PP_MakeOptionalCompletionCallback(
                                    &MockCompletionCallback::Callback, cb));

    if (expected_shm_msg) {
      uint32_t shm_id, shm_size, expected_shm_id, expected_shm_size;
      UnpackMessage<PpapiHostMsg_VideoDecoder_GetShm>(
          *expected_shm_msg, &expected_shm_id, &expected_shm_size);
      if (shm_msg_handler.last_handled_msg().type() == 0 ||
          !UnpackMessage<PpapiHostMsg_VideoDecoder_GetShm>(
              shm_msg_handler.last_handled_msg(), &shm_id, &shm_size) ||
          shm_id != expected_shm_id ||
          shm_size != expected_shm_size) {
        // Signal that the expected shm message wasn't sent by failing.
        result = PP_ERROR_FAILED;
      }
    }

    sink().RemoveFilter(&shm_msg_handler);
    return result;
  }

  int32_t CallGetPicture(PP_Resource pp_decoder,
                         PP_VideoPicture* picture,
                         MockCompletionCallback* cb) {
    int32_t result =
        decoder_iface()->GetPicture(pp_decoder,
                                    picture,
                                    PP_MakeOptionalCompletionCallback(
                                        &MockCompletionCallback::Callback, cb));
    return result;
  }

  void CallRecyclePicture(PP_Resource pp_decoder,
                          const PP_VideoPicture& picture) {
    decoder_iface()->RecyclePicture(pp_decoder, &picture);
  }

  int32_t CallFlush(PP_Resource pp_decoder, MockCompletionCallback* cb) {
    int32_t result =
        decoder_iface()->Flush(pp_decoder,
                               PP_MakeOptionalCompletionCallback(
                                   &MockCompletionCallback::Callback, cb));
    return result;
  }

  int32_t CallReset(PP_Resource pp_decoder, MockCompletionCallback* cb) {
    int32_t result =
        decoder_iface()->Reset(pp_decoder,
                               PP_MakeOptionalCompletionCallback(
                                   &MockCompletionCallback::Callback, cb));
    return result;
  }

  void SendDecodeReply(const ResourceMessageCallParams& params,
                       uint32_t shm_id) {
    SendReply(params, PP_OK, PpapiPluginMsg_VideoDecoder_DecodeReply(shm_id));
  }

  void SendPictureReady(const ResourceMessageCallParams& params,
                        uint32_t decode_count,
                        uint32_t texture_id) {
    SendReply(
        params,
        PP_OK,
        PpapiPluginMsg_VideoDecoder_PictureReady(decode_count, texture_id));
  }

  void SendFlushReply(const ResourceMessageCallParams& params) {
    SendReply(params, PP_OK, PpapiPluginMsg_VideoDecoder_FlushReply());
  }

  void SendResetReply(const ResourceMessageCallParams& params) {
    SendReply(params, PP_OK, PpapiPluginMsg_VideoDecoder_ResetReply());
  }

  void SendRequestTextures(const ResourceMessageCallParams& params) {
    SendReply(params,
              PP_OK,
              PpapiPluginMsg_VideoDecoder_RequestTextures(
                  kNumRequestedTextures,
                  PP_MakeSize(320, 240),
                  GL_TEXTURE_2D,
                  std::vector<gpu::Mailbox>()));
  }

  void SendNotifyError(const ResourceMessageCallParams& params, int32_t error) {
    SendReply(params, PP_OK, PpapiPluginMsg_VideoDecoder_NotifyError(error));
  }

  bool CheckDecodeMsg(ResourceMessageCallParams* params,
                      uint32_t* shm_id,
                      uint32_t* size,
                      int32_t* decode_id) {
    IPC::Message msg;
    if (!sink().GetFirstResourceCallMatching(
            PpapiHostMsg_VideoDecoder_Decode::ID, params, &msg))
      return false;
    sink().ClearMessages();
    return UnpackMessage<PpapiHostMsg_VideoDecoder_Decode>(
        msg, shm_id, size, decode_id);
  }

  bool CheckRecyclePictureMsg(ResourceMessageCallParams* params,
                              uint32_t* texture_id) {
    IPC::Message msg;
    if (!sink().GetFirstResourceCallMatching(
            PpapiHostMsg_VideoDecoder_RecyclePicture::ID, params, &msg))
      return false;
    sink().ClearMessages();
    return UnpackMessage<PpapiHostMsg_VideoDecoder_RecyclePicture>(msg,
                                                                   texture_id);
  }

  bool CheckFlushMsg(ResourceMessageCallParams* params) {
    return CheckMsg(params, PpapiHostMsg_VideoDecoder_Flush::ID);
  }

  bool CheckResetMsg(ResourceMessageCallParams* params) {
    return CheckMsg(params, PpapiHostMsg_VideoDecoder_Reset::ID);
  }

  void ClearCallbacks(PP_Resource pp_decoder) {
    ResourceMessageCallParams params;
    MockCompletionCallback cb;

    // Reset to abort Decode and GetPicture callbacks.
    CallReset(pp_decoder, &cb);
    // Initialize params so we can reply to the Reset.
    CheckResetMsg(&params);
    // Run the Reset callback.
    SendResetReply(params);
  }

 private:
  bool CheckMsg(ResourceMessageCallParams* params, int id) {
    IPC::Message msg;
    if (!sink().GetFirstResourceCallMatching(id, params, &msg))
      return false;
    sink().ClearMessages();
    return true;
  }

  const PPB_VideoDecoder_0_2* decoder_iface_;

  char decode_buffer_[kDecodeBufferSize];
};

}  // namespace

TEST_F(VideoDecoderResourceTest, Initialize) {
  // Initialize with 0 graphics3d_context should fail.
  {
    LockingResourceReleaser decoder(CreateDecoder());
    MockCompletionCallback cb;
    int32_t result = decoder_iface()->Initialize(
        decoder.get(),
        0 /* invalid 3d graphics */,
        PP_VIDEOPROFILE_H264MAIN,
        PP_HARDWAREACCELERATION_WITHFALLBACK,
        PP_MakeOptionalCompletionCallback(&MockCompletionCallback::Callback,
                                          &cb));
    ASSERT_EQ(PP_ERROR_BADRESOURCE, result);
  }
  // Initialize with bad profile value should fail.
  {
    LockingResourceReleaser decoder(CreateDecoder());
    MockCompletionCallback cb;
    int32_t result = decoder_iface()->Initialize(
        decoder.get(),
        1 /* non-zero resource */,
        static_cast<PP_VideoProfile>(-1),
        PP_HARDWAREACCELERATION_WITHFALLBACK,
        PP_MakeOptionalCompletionCallback(&MockCompletionCallback::Callback,
                                          &cb));
    ASSERT_EQ(PP_ERROR_BADARGUMENT, result);
  }
  // Initialize with valid graphics3d_context and profile should succeed.
  {
    LockingResourceReleaser decoder(CreateDecoder());
    LockingResourceReleaser graphics3d(CreateGraphics3d());
    MockCompletionCallback cb;
    int32_t result = decoder_iface()->Initialize(
        decoder.get(),
        graphics3d.get(),
        PP_VIDEOPROFILE_H264MAIN,
        PP_HARDWAREACCELERATION_WITHFALLBACK,
        PP_MakeOptionalCompletionCallback(&MockCompletionCallback::Callback,
                                          &cb));
    ASSERT_EQ(PP_OK_COMPLETIONPENDING, result);
    ASSERT_TRUE(decoder_iface()->IsVideoDecoder(decoder.get()));

    // Another attempt while pending should fail.
    result = decoder_iface()->Initialize(
        decoder.get(),
        graphics3d.get(),
        PP_VIDEOPROFILE_H264MAIN,
        PP_HARDWAREACCELERATION_WITHFALLBACK,
        PP_MakeOptionalCompletionCallback(&MockCompletionCallback::Callback,
                                          &cb));
    ASSERT_EQ(PP_ERROR_INPROGRESS, result);

    // Check for host message and send a reply to complete initialization.
    ResourceMessageCallParams params;
    IPC::Message msg;
    ASSERT_TRUE(sink().GetFirstResourceCallMatching(
        PpapiHostMsg_VideoDecoder_Initialize::ID, &params, &msg));
    sink().ClearMessages();
    SendReply(params, PP_OK, PpapiPluginMsg_VideoDecoder_InitializeReply());
    ASSERT_TRUE(cb.called());
    ASSERT_EQ(PP_OK, cb.result());
  }
}

TEST_F(VideoDecoderResourceTest, Uninitialized) {
  // Operations on uninitialized decoders should fail.
  LockingResourceReleaser decoder(CreateDecoder());
  MockCompletionCallback uncalled_cb;

  ASSERT_EQ(PP_ERROR_FAILED, CallDecode(decoder.get(), &uncalled_cb, NULL));
  ASSERT_FALSE(uncalled_cb.called());

  ASSERT_EQ(PP_ERROR_FAILED, CallGetPicture(decoder.get(), NULL, &uncalled_cb));
  ASSERT_FALSE(uncalled_cb.called());

  ASSERT_EQ(PP_ERROR_FAILED, CallFlush(decoder.get(), &uncalled_cb));
  ASSERT_FALSE(uncalled_cb.called());

  ASSERT_EQ(PP_ERROR_FAILED, CallReset(decoder.get(), &uncalled_cb));
  ASSERT_FALSE(uncalled_cb.called());
}

// TODO(bbudge) Fix sync message testing on Windows 64 bit builds. The reply
// message for GetShm isn't received, causing Decode to fail.
// http://crbug.com/379260
#if !defined(OS_WIN) || !defined(ARCH_CPU_64_BITS)
TEST_F(VideoDecoderResourceTest, DecodeAndGetPicture) {
  LockingResourceReleaser decoder(CreateAndInitializeDecoder());
  ResourceMessageCallParams params, params2;
  MockCompletionCallback decode_cb, get_picture_cb, uncalled_cb;

  uint32_t shm_id;
  uint32_t decode_size;
  int32_t decode_id;
  // Call Decode until we have the maximum pending, minus one.
  for (uint32_t i = 0; i < kMaximumPendingDecodes - 1; i++) {
    PpapiHostMsg_VideoDecoder_GetShm shm_msg(i, kDecodeBufferSize);
    ASSERT_EQ(PP_OK, CallDecode(decoder.get(), &uncalled_cb, &shm_msg));
    ASSERT_FALSE(uncalled_cb.called());
    CheckDecodeMsg(&params, &shm_id, &decode_size, &decode_id);
    ASSERT_EQ(i, shm_id);
    ASSERT_EQ(kDecodeBufferSize, decode_size);
    // The resource generates uids internally, starting at 1.
    int32_t uid = i + 1;
    ASSERT_EQ(uid, decode_id);
  }
  // Once we've allocated the maximum number of buffers, we must wait.
  PpapiHostMsg_VideoDecoder_GetShm shm_msg(7U, kDecodeBufferSize);
  ASSERT_EQ(PP_OK_COMPLETIONPENDING,
            CallDecode(decoder.get(), &decode_cb, &shm_msg));
  CheckDecodeMsg(&params, &shm_id, &decode_size, &decode_id);
  ASSERT_EQ(7U, shm_id);
  ASSERT_EQ(kDecodeBufferSize, decode_size);

  // Calling Decode when another Decode is pending should fail.
  ASSERT_EQ(PP_ERROR_INPROGRESS, CallDecode(decoder.get(), &uncalled_cb, NULL));
  ASSERT_FALSE(uncalled_cb.called());
  // Free up the first decode buffer.
  SendDecodeReply(params, 0U);
  // The decoder should run the pending callback.
  ASSERT_TRUE(decode_cb.called());
  ASSERT_EQ(PP_OK, decode_cb.result());
  decode_cb.Reset();

  // Now try to get a picture. No picture ready message has been received yet.
  PP_VideoPicture picture;
  ASSERT_EQ(PP_OK_COMPLETIONPENDING,
            CallGetPicture(decoder.get(), &picture, &get_picture_cb));
  ASSERT_FALSE(get_picture_cb.called());
  // Calling GetPicture when another GetPicture is pending should fail.
  ASSERT_EQ(PP_ERROR_INPROGRESS,
            CallGetPicture(decoder.get(), &picture, &uncalled_cb));
  ASSERT_FALSE(uncalled_cb.called());
  // Send 'request textures' message to initialize textures.
  SendRequestTextures(params);
  // Send a picture ready message for Decode call 1. The GetPicture callback
  // should complete.
  SendPictureReady(params, 1U, kTextureId1);
  ASSERT_TRUE(get_picture_cb.called());
  ASSERT_EQ(PP_OK, get_picture_cb.result());
  ASSERT_EQ(kDecodeId, picture.decode_id);
  get_picture_cb.Reset();

  // Send a picture ready message for Decode call 2. Since there is no pending
  // GetPicture call, the picture should be queued.
  SendPictureReady(params, 2U, kTextureId2);
  // The next GetPicture should return synchronously.
  ASSERT_EQ(PP_OK, CallGetPicture(decoder.get(), &picture, &uncalled_cb));
  ASSERT_FALSE(uncalled_cb.called());
  ASSERT_EQ(kDecodeId, picture.decode_id);
}
#endif  // !defined(OS_WIN) || !defined(ARCH_CPU_64_BITS)

// TODO(bbudge) Fix sync message testing on Windows 64 bit builds. The reply
// message for GetShm isn't received, causing Decode to fail.
// http://crbug.com/379260
#if !defined(OS_WIN) || !defined(ARCH_CPU_64_BITS)
TEST_F(VideoDecoderResourceTest, RecyclePicture) {
  LockingResourceReleaser decoder(CreateAndInitializeDecoder());
  ResourceMessageCallParams params;
  MockCompletionCallback decode_cb, get_picture_cb, uncalled_cb;

  // Get to a state where we have a picture to recycle.
  PpapiHostMsg_VideoDecoder_GetShm shm_msg(0U, kDecodeBufferSize);
  ASSERT_EQ(PP_OK, CallDecode(decoder.get(), &decode_cb, &shm_msg));
  uint32_t shm_id;
  uint32_t decode_size;
  int32_t decode_id;
  CheckDecodeMsg(&params, &shm_id, &decode_size, &decode_id);
  SendDecodeReply(params, 0U);
  // Send 'request textures' message to initialize textures.
  SendRequestTextures(params);
  // Call GetPicture and send 'picture ready' message to get a picture to
  // recycle.
  PP_VideoPicture picture;
  ASSERT_EQ(PP_OK_COMPLETIONPENDING,
            CallGetPicture(decoder.get(), &picture, &get_picture_cb));
  SendPictureReady(params, 0U, kTextureId1);
  ASSERT_EQ(kTextureId1, picture.texture_id);

  CallRecyclePicture(decoder.get(), picture);
  uint32_t texture_id;
  ASSERT_TRUE(CheckRecyclePictureMsg(&params, &texture_id));
  ASSERT_EQ(kTextureId1, texture_id);

  ClearCallbacks(decoder.get());
}
#endif  // !defined(OS_WIN) || !defined(ARCH_CPU_64_BITS)

TEST_F(VideoDecoderResourceTest, Flush) {
  LockingResourceReleaser decoder(CreateAndInitializeDecoder());
  ResourceMessageCallParams params, params2;
  MockCompletionCallback flush_cb, get_picture_cb, uncalled_cb;

  ASSERT_EQ(PP_OK_COMPLETIONPENDING, CallFlush(decoder.get(), &flush_cb));
  ASSERT_FALSE(flush_cb.called());
  ASSERT_TRUE(CheckFlushMsg(&params));

  ASSERT_EQ(PP_ERROR_FAILED, CallDecode(decoder.get(), &uncalled_cb, NULL));
  ASSERT_FALSE(uncalled_cb.called());

  // Plugin can call GetPicture while Flush is pending.
  ASSERT_EQ(PP_OK_COMPLETIONPENDING,
            CallGetPicture(decoder.get(), NULL, &get_picture_cb));
  ASSERT_FALSE(get_picture_cb.called());

  ASSERT_EQ(PP_ERROR_INPROGRESS, CallFlush(decoder.get(), &uncalled_cb));
  ASSERT_FALSE(uncalled_cb.called());

  ASSERT_EQ(PP_ERROR_FAILED, CallReset(decoder.get(), &uncalled_cb));
  ASSERT_FALSE(uncalled_cb.called());

  // Plugin can call RecyclePicture while Flush is pending.
  PP_VideoPicture picture;
  picture.texture_id = kTextureId1;
  CallRecyclePicture(decoder.get(), picture);
  uint32_t texture_id;
  ASSERT_TRUE(CheckRecyclePictureMsg(&params2, &texture_id));

  SendFlushReply(params);
  // Any pending GetPicture call is aborted.
  ASSERT_TRUE(get_picture_cb.called());
  ASSERT_EQ(PP_ERROR_ABORTED, get_picture_cb.result());
  ASSERT_TRUE(flush_cb.called());
  ASSERT_EQ(PP_OK, flush_cb.result());
}

// TODO(bbudge) Test Reset when we can run the message loop to get aborted
// callbacks to run.

// TODO(bbudge) Fix sync message testing on Windows 64 bit builds. The reply
// message for GetShm isn't received, causing Decode to fail.
// http://crbug.com/379260
#if !defined(OS_WIN) || !defined(ARCH_CPU_64_BITS)
TEST_F(VideoDecoderResourceTest, NotifyError) {
  LockingResourceReleaser decoder(CreateAndInitializeDecoder());
  ResourceMessageCallParams params;
  MockCompletionCallback decode_cb, get_picture_cb, uncalled_cb;

  // Call Decode and GetPicture to have some pending requests.
  PpapiHostMsg_VideoDecoder_GetShm shm_msg(0U, kDecodeBufferSize);
  ASSERT_EQ(PP_OK, CallDecode(decoder.get(), &decode_cb, &shm_msg));
  ASSERT_FALSE(decode_cb.called());
  ASSERT_EQ(PP_OK_COMPLETIONPENDING,
            CallGetPicture(decoder.get(), NULL, &get_picture_cb));
  ASSERT_FALSE(get_picture_cb.called());

  // Send the decoder resource an unsolicited notify error message. We first
  // need to initialize 'params' so the message is routed to the decoder.
  uint32_t shm_id;
  uint32_t decode_size;
  int32_t decode_id;
  CheckDecodeMsg(&params, &shm_id, &decode_size, &decode_id);
  SendNotifyError(params, PP_ERROR_RESOURCE_FAILED);

  // Any pending message should be run with the reported error.
  ASSERT_TRUE(get_picture_cb.called());
  ASSERT_EQ(PP_ERROR_RESOURCE_FAILED, get_picture_cb.result());

  // All further calls return the reported error.
  ASSERT_EQ(PP_ERROR_RESOURCE_FAILED,
            CallDecode(decoder.get(), &uncalled_cb, NULL));
  ASSERT_FALSE(uncalled_cb.called());
  ASSERT_EQ(PP_ERROR_RESOURCE_FAILED,
            CallGetPicture(decoder.get(), NULL, &uncalled_cb));
  ASSERT_FALSE(uncalled_cb.called());
  ASSERT_EQ(PP_ERROR_RESOURCE_FAILED, CallFlush(decoder.get(), &uncalled_cb));
  ASSERT_FALSE(uncalled_cb.called());
  ASSERT_EQ(PP_ERROR_RESOURCE_FAILED, CallReset(decoder.get(), &uncalled_cb));
  ASSERT_FALSE(uncalled_cb.called());
}
#endif  // !defined(OS_WIN) || !defined(ARCH_CPU_64_BITS)

}  // namespace proxy
}  // namespace ppapi
