// 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 <stddef.h>
#include <stdint.h>

#include "base/memory/shared_memory.h"
#include "base/message_loop/message_loop.h"
#include "build/build_config.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;
#if !defined(OS_WIN) || !defined(ARCH_CPU_64_BITS)
const uint32_t kTextureId2 = 2;
#endif
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_1_1_Thunk()) {}

  const PPB_VideoDecoder_1_1* 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, gfx::Size(640, 480)));
    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,
        0,
        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);

    std::unique_ptr<SerializedHandle> serialized_handle;
    base::SharedMemory shm;
    if (expected_shm_msg) {
      shm.CreateAnonymous(kShmSize);
      base::SharedMemoryHandle shm_handle = shm.handle().Duplicate();
      serialized_handle.reset(new SerializedHandle(shm_handle, kShmSize));
      shm_msg_handler.set_serialized_handle(serialized_handle.get());
    }

    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) {
    PP_Rect visible_rect = PP_MakeRectFromXYWH(0, 0, 640, 480);
    SendReply(params, PP_OK, PpapiPluginMsg_VideoDecoder_PictureReady(
                                 decode_count, texture_id, visible_rect));
  }

  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_1_1* 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,
        0,
        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,
        0,
        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,
        0,
        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,
        0,
        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
