15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef PPAPI_TESTS_TEST_UTILS_H_
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define PPAPI_TESTS_TEST_UTILS_H_
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/c/pp_instance.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/c/pp_stdint.h"
12f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ppapi/c/private/ppb_testing_private.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/cpp/completion_callback.h"
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ppapi/cpp/message_loop.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/utility/completion_callback_factory.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)namespace pp {
18eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochclass NetAddress;
197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Timeout to wait for some action to complete.
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern const int kActionTimeoutMs;
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)const PPB_Testing_Private* GetTestingInterface();
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string ReportError(const char* method, int32_t error);
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PlatformSleep(int duration_ms);
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool GetLocalHostPort(PP_Instance instance, std::string* host, uint16_t* port);
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)uint16_t ConvertFromNetEndian16(uint16_t x);
30868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)uint16_t ConvertToNetEndian16(uint16_t x);
31eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochbool EqualNetAddress(const pp::NetAddress& addr1, const pp::NetAddress& addr2);
327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// Only returns the first address if there are more than one available.
337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)bool ResolveHost(PP_Instance instance,
347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                 const std::string& host,
357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                 uint16_t port,
36eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                 pp::NetAddress* addr);
3768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)bool ReplacePort(PP_Instance instance,
3868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                 const pp::NetAddress& input_addr,
3968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                 uint16_t port,
4068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                 pp::NetAddress* output_addr);
4168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)uint16_t GetPort(const pp::NetAddress& addr);
42868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// NestedEvent allows you to run a nested MessageLoop and wait for a particular
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// event to complete. For example, you can use it to wait for a callback on a
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// PPP interface, which will "Signal" the event and make the loop quit.
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// "Wait()" will return immediately if it has already been signalled. Otherwise,
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// it will run a nested message loop (using PPB_Testing.RunMessageLoop) and will
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// return only after it has been signalled.
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Example:
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  std::string TestFullscreen::TestNormalToFullscreen() {
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//    pp::Fullscreen screen_mode(instance);
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//    screen_mode.SetFullscreen(true);
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//    SimulateUserGesture();
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//    // Let DidChangeView run in a nested message loop.
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//    nested_event_.Wait();
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//    Pass();
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  }
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  void TestFullscreen::DidChangeView(const pp::View& view) {
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//    nested_event_.Signal();
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  }
62c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//
63c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// All methods except Signal and PostSignal must be invoked on the main thread.
64c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// It's OK to signal from a background thread, so you can (for example) Signal()
65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// from the Audio thread.
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class NestedEvent {
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit NestedEvent(PP_Instance instance)
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : instance_(instance), waiting_(false), signalled_(false) {
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Run a nested message loop and wait until Signal() is called. If Signal()
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // has already been called, return immediately without running a nested loop.
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Wait();
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Signal the NestedEvent. If Wait() has been called, quit the message loop.
75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // This can be called from any thread.
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Signal();
77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Signal the NestedEvent in |wait_ms| milliseconds. This can be called from
78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // any thread.
79c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void PostSignal(int32_t wait_ms);
80c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Reset the NestedEvent so it can be used again.
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Reset();
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void SignalOnMainThread();
85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  static void SignalThunk(void* async_event, int32_t result);
86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PP_Instance instance_;
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool waiting_;
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool signalled_;
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Disable copy and assign.
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NestedEvent(const NestedEvent&);
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NestedEvent& operator=(const NestedEvent&);
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)enum CallbackType { PP_REQUIRED, PP_OPTIONAL, PP_BLOCKING };
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class TestCompletionCallback {
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  class Delegate {
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   public:
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    virtual ~Delegate() {}
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    virtual void OnCallback(void* user_data, int32_t result) = 0;
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit TestCompletionCallback(PP_Instance instance);
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(dmichael): Remove this constructor.
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback(PP_Instance instance, bool force_async);
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback(PP_Instance instance, CallbackType callback_type);
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Sets a Delegate instance. OnCallback() of this instance will be invoked
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // when the completion callback is invoked.
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The delegate will be reset when Reset() or GetCallback() is called.
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SetDelegate(Delegate* delegate) { delegate_ = delegate; }
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Wait for a result, given the return from the call which took this callback
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // as a parameter. If |result| is PP_OK_COMPLETIONPENDING, WaitForResult will
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // block until its callback has been invoked (in some cases, this will already
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // have happened, and WaitForCallback can return immediately).
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // For any other values, WaitForResult will simply set its internal "result_"
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // field. To retrieve the final result of the operation (i.e., the result
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the callback has run, if necessary), call result(). You can call result()
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // as many times as necessary until a new pp::CompletionCallback is retrieved.
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // In some cases, you may want to check that the callback was invoked in the
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // expected way (i.e., if the callback was "Required", then it should be
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // invoked asynchronously). Within the body of a test (where returning a non-
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // empty string indicates test failure), you can use the
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // CHECK_CALLBACK_BEHAVIOR(callback) macro. From within a helper function,
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // you can use failed() and errors().
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Example usage within a test:
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //  callback.WaitForResult(foo.DoSomething(callback));
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //  CHECK_CALLBACK_BEHAVIOR(callback);
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //  ASSERT_EQ(PP_OK, callback.result());
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Example usage within a helper function:
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //  void HelperFunction(std::string* error_message) {
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //    callback.WaitForResult(foo.DoSomething(callback));
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //    if (callback.failed())
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //      error_message->assign(callback.errors());
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //  }
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void WaitForResult(int32_t result);
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Used when you expect to receive either synchronous completion with PP_OK
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // or a PP_ERROR_ABORTED asynchronously.
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //  Example usage:
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //  int32_t result = 0;
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //  {
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //    pp::URLLoader temp(instance_);
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //    result = temp.Open(request, callback);
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //  }
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //  callback.WaitForAbortResult(result);
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //  CHECK_CALLBACK_BEHAVIOR(callback);
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void WaitForAbortResult(int32_t result);
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Retrieve a pp::CompletionCallback for use in testing. This Reset()s the
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TestCompletionCallback.
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pp::CompletionCallback GetCallback();
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool failed() { return !errors_.empty(); }
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string& errors() { return errors_; }
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int32_t result() const { return result_; }
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Reset so that this callback can be used again.
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Reset();
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
167c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CallbackType callback_type() { return callback_type_; }
168c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void set_target_loop(const pp::MessageLoop& loop) { target_loop_ = loop; }
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void Handler(void* user_data, int32_t result);
170c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
171c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) protected:
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void RunMessageLoop();
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void QuitMessageLoop();
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Used to check that WaitForResult is only called once for each usage of the
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // callback.
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool wait_for_result_called_;
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Indicates whether we have already been invoked.
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool have_result_;
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The last result received (or PP_OK_COMPLETIONCALLBACK if none).
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int32_t result_;
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CallbackType callback_type_;
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool post_quit_task_;
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string errors_;
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PP_Instance instance_;
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Delegate* delegate_;
1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  pp::MessageLoop target_loop_;
1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
190c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace internal {
191c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
192c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)template <typename OutputT, typename CallbackT>
193c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class TestCompletionCallbackWithOutputBase {
1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
195c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  explicit TestCompletionCallbackWithOutputBase(PP_Instance instance)
1967dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      : callback_(instance),
1977dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        output_storage_() {
1987dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    CallbackT::TraitsType::Initialize(&output_storage_);
1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
201c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestCompletionCallbackWithOutputBase(PP_Instance instance, bool force_async)
2027dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      : callback_(instance, force_async),
2037dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        output_storage_() {
2047dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    CallbackT::TraitsType::Initialize(&output_storage_);
2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
207c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestCompletionCallbackWithOutputBase(PP_Instance instance,
208c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                       CallbackType callback_type)
2097dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      : callback_(instance, callback_type),
2107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        output_storage_() {
2117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    CallbackT::TraitsType::Initialize(&output_storage_);
2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
214c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CallbackT GetCallback();
215c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  OutputT output() {
216c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return CallbackT::TraitsType::StorageToPluginArg(
217c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        output_storage_);
2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
220c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Delegate functions to TestCompletionCallback
221c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void SetDelegate(TestCompletionCallback::Delegate* delegate) {
222c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    callback_.SetDelegate(delegate);
223c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
224c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void WaitForResult(int32_t result) { callback_.WaitForResult(result); }
225c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void WaitForAbortResult(int32_t result) {
226c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    callback_.WaitForAbortResult(result);
227c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
228c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  bool failed() { return callback_.failed(); }
229c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const std::string& errors() { return callback_.errors(); }
230c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  int32_t result() const { return callback_.result(); }
2317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  void Reset() {
2327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    CallbackT::TraitsType::Initialize(&output_storage_);
2337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    return callback_.Reset();
2347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
236c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private:
237c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestCompletionCallback callback_;
238c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  typename CallbackT::OutputStorageType output_storage_;
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
241c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)template <typename OutputT, typename CallbackT>
242c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)CallbackT
243c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TestCompletionCallbackWithOutputBase<OutputT, CallbackT>::GetCallback() {
2447dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  this->Reset();
245c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (callback_.callback_type() == PP_BLOCKING) {
246c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    CallbackT cc(&output_storage_);
2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return cc;
2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
250c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  callback_.set_target_loop(pp::MessageLoop::GetCurrent());
251c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CallbackT cc(&TestCompletionCallback::Handler, this, &output_storage_);
252c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (callback_.callback_type() == PP_OPTIONAL)
2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    cc.set_flags(PP_COMPLETIONCALLBACK_FLAG_OPTIONAL);
2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return cc;
2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
257c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}  // namespace internal
258c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
259c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)template <typename OutputT>
260c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class TestCompletionCallbackWithOutput
261c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    : public internal::TestCompletionCallbackWithOutputBase<
262c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        OutputT, pp::CompletionCallbackWithOutput<OutputT> > {
263c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public:
264c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  explicit TestCompletionCallbackWithOutput(PP_Instance instance)
265c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      : BaseType(instance) {
266c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
267c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
268c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestCompletionCallbackWithOutput(PP_Instance instance, bool force_async)
269c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      : BaseType(instance, force_async) {
270c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
271c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
272c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestCompletionCallbackWithOutput(PP_Instance instance,
273c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                   CallbackType callback_type)
274c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      : BaseType(instance, callback_type) {
275c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
276c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
277c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private:
278c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  typedef internal::TestCompletionCallbackWithOutputBase<
279c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      OutputT, pp::CompletionCallbackWithOutput<OutputT> > BaseType;
280c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)};
281c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
282c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)template <typename OutputT>
283c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class TestExtCompletionCallbackWithOutput
284c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    : public internal::TestCompletionCallbackWithOutputBase<
285c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        OutputT, pp::ext::ExtCompletionCallbackWithOutput<OutputT> > {
286c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public:
287c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  explicit TestExtCompletionCallbackWithOutput(PP_Instance instance)
288c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      : BaseType(instance) {
289c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
290c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
291c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestExtCompletionCallbackWithOutput(PP_Instance instance, bool force_async)
292c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      : BaseType(instance, force_async) {
293c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
294c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
295c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestExtCompletionCallbackWithOutput(PP_Instance instance,
296c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                      CallbackType callback_type)
297c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      : BaseType(instance, callback_type) {
298c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
299c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
300c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private:
301c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  typedef internal::TestCompletionCallbackWithOutputBase<
302c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      OutputT, pp::ext::ExtCompletionCallbackWithOutput<OutputT> > BaseType;
303c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)};
3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Verifies that the callback didn't record any errors. If the callback is run
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// in an unexpected way (e.g., if it's invoked asynchronously when the call
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// should have blocked), this returns an appropriate error string.
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define CHECK_CALLBACK_BEHAVIOR(callback) \
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)do { \
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if ((callback).failed()) \
311c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return MakeFailureMessage(__FILE__, __LINE__, \
312c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                              (callback).errors().c_str()); \
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} while (false)
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * A set of macros to use for platform detection. These were largely copied
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * from chromium's build_config.h.
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(__APPLE__)
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define PPAPI_OS_MACOSX 1
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(ANDROID)
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define PPAPI_OS_ANDROID 1
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(__native_client__)
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define PPAPI_OS_NACL 1
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(__linux__)
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define PPAPI_OS_LINUX 1
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(_WIN32)
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define PPAPI_OS_WIN 1
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(__FreeBSD__)
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define PPAPI_OS_FREEBSD 1
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(__OpenBSD__)
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define PPAPI_OS_OPENBSD 1
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(__sun)
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define PPAPI_OS_SOLARIS 1
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#error Please add support for your platform in ppapi/tests/test_utils.h
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* These are used to determine POSIX-like implementations vs Windows. */
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__) || \
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    defined(__OpenBSD__) || defined(__sun) || defined(__native_client__)
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define PPAPI_POSIX 1
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // PPAPI_TESTS_TEST_UTILS_H_
346