| Index: ppapi/tests/test_utils.h
|
| diff --git a/ppapi/tests/test_utils.h b/ppapi/tests/test_utils.h
|
| index 8cff24e15f172e2f2f84759fc9223341ed675005..1e2ec369316475accbd41d986e2a22f40d0d1bb0 100644
|
| --- a/ppapi/tests/test_utils.h
|
| +++ b/ppapi/tests/test_utils.h
|
| @@ -1,4 +1,4 @@
|
| -// Copyright (c) 2011 The Chromium Authors. All rights reserved.
|
| +// Copyright (c) 2012 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.
|
|
|
| @@ -11,6 +11,7 @@
|
| #include "ppapi/c/pp_instance.h"
|
| #include "ppapi/c/pp_stdint.h"
|
| #include "ppapi/cpp/completion_callback.h"
|
| +#include "ppapi/utility/completion_callback_factory.h"
|
|
|
| // Timeout to wait for some action to complete.
|
| extern const int kActionTimeoutMs;
|
| @@ -20,36 +21,149 @@ std::string ReportError(const char* method, int32_t error);
|
| void PlatformSleep(int duration_ms);
|
| bool GetLocalHostPort(PP_Instance instance, std::string* host, uint16_t* port);
|
|
|
| +// NestedEvent allows you to run a nested MessageLoop and wait for a particular
|
| +// event to complete. For example, you can use it to wait for a callback on a
|
| +// PPP interface, which will "Signal" the event and make the loop quit.
|
| +// "Wait()" will return immediately if it has already been signalled. Otherwise,
|
| +// it will run a nested message loop (using PPB_Testing.RunMessageLoop) and will
|
| +// return only after it has been signalled.
|
| +// Example:
|
| +// std::string TestFullscreen::TestNormalToFullscreen() {
|
| +// pp::Fullscreen screen_mode(instance);
|
| +// screen_mode.SetFullscreen(true);
|
| +// SimulateUserGesture();
|
| +// // Let DidChangeView run in a nested message loop.
|
| +// nested_event_.Wait();
|
| +// Pass();
|
| +// }
|
| +//
|
| +// void TestFullscreen::DidChangeView(const pp::View& view) {
|
| +// nested_event_.Signal();
|
| +// }
|
| +class NestedEvent {
|
| + public:
|
| + explicit NestedEvent(PP_Instance instance)
|
| + : instance_(instance), waiting_(false), signalled_(false) {
|
| + }
|
| + // Run a nested message loop and wait until Signal() is called. If Signal()
|
| + // has already been called, return immediately without running a nested loop.
|
| + void Wait();
|
| + // Signal the NestedEvent. If Wait() has been called, quit the message loop.
|
| + void Signal();
|
| + private:
|
| + PP_Instance instance_;
|
| + bool waiting_;
|
| + bool signalled_;
|
| + // Disable copy and assign.
|
| + NestedEvent(const NestedEvent&);
|
| + NestedEvent& operator=(const NestedEvent&);
|
| +};
|
| +
|
| +enum CallbackType { PP_REQUIRED, PP_OPTIONAL, PP_BLOCKING };
|
| class TestCompletionCallback {
|
| public:
|
| - TestCompletionCallback(PP_Instance instance);
|
| + explicit TestCompletionCallback(PP_Instance instance);
|
| + // TODO(dmichael): Remove this constructor.
|
| TestCompletionCallback(PP_Instance instance, bool force_async);
|
|
|
| + TestCompletionCallback(PP_Instance instance, CallbackType callback_type);
|
| +
|
| // Waits for the callback to be called and returns the
|
| // result. Returns immediately if the callback was previously called
|
| // and the result wasn't returned (i.e. each result value received
|
| // by the callback is returned by WaitForResult() once and only
|
| - // once).
|
| + // once). DEPRECATED: Please use the one below.
|
| + // TODO(dmichael): Remove this one when all the tests are updated.
|
| int32_t WaitForResult();
|
|
|
| - operator pp::CompletionCallback() const;
|
| + // Wait for a result, given the return from the call which took this callback
|
| + // as a parameter. If |result| is PP_OK_COMPLETIONPENDING, WaitForResult will
|
| + // block until its callback has been invoked (in some cases, this will already
|
| + // have happened, and WaitForCallback can return immediately).
|
| + // For any other values, WaitForResult will simply set its internal "result_"
|
| + // field. To retrieve the final result of the operation (i.e., the result
|
| + // the callback has run, if necessary), call result(). You can call result()
|
| + // as many times as necessary until a new pp::CompletionCallback is retrieved.
|
| + //
|
| + // In some cases, you may want to check that the callback was invoked in the
|
| + // expected way (i.e., if the callback was "Required", then it should be
|
| + // invoked asynchronously). Within the body of a test (where returning a non-
|
| + // empty string indicates test failure), you can use the
|
| + // CHECK_CALLBACK_BEHAVIOR(callback) macro. From within a helper function,
|
| + // you can use failed() and errors().
|
| + //
|
| + // Example usage within a test:
|
| + // callback.WaitForResult(foo.DoSomething(callback));
|
| + // CHECK_CALLBACK_BEHAVIOR(callback);
|
| + // ASSERT_EQ(PP_OK, callback.result());
|
| + //
|
| + // Example usage within a helper function:
|
| + // void HelperFunction(std::string* error_message) {
|
| + // callback.WaitForResult(foo.DoSomething(callback));
|
| + // if (callback.failed())
|
| + // error_message->assign(callback.errors());
|
| + // }
|
| + void WaitForResult(int32_t result);
|
|
|
| + // Used when you expect to receive either synchronous completion with PP_OK
|
| + // or a PP_ERROR_ABORTED asynchronously.
|
| + // Example usage:
|
| + // int32_t result = 0;
|
| + // {
|
| + // pp::URLLoader temp(instance_);
|
| + // result = temp.Open(request, callback);
|
| + // }
|
| + // callback.WaitForAbortResult(result);
|
| + // CHECK_CALLBACK_BEHAVIOR(callback);
|
| + void WaitForAbortResult(int32_t result);
|
| +
|
| + // Retrieve a pp::CompletionCallback for use in testing. This Reset()s the
|
| + // TestCompletionCallback.
|
| + pp::CompletionCallback GetCallback();
|
| + operator pp::CompletionCallback() {
|
| + return GetCallback();
|
| + }
|
| +
|
| + // TODO(dmichael): Remove run_count when all tests are updated. Most cases
|
| + // that use this can simply use CHECK_CALLBACK_BEHAVIOR.
|
| unsigned run_count() const { return run_count_; }
|
| + // TODO(dmichael): Remove this; tests should use Reset() instead.
|
| void reset_run_count() { run_count_ = 0; }
|
|
|
| + bool failed() { return !errors_.empty(); }
|
| + const std::string& errors() { return errors_; }
|
| +
|
| int32_t result() const { return result_; }
|
|
|
| + // Reset so that this callback can be used again.
|
| + void Reset();
|
| +
|
| private:
|
| static void Handler(void* user_data, int32_t result);
|
|
|
| + // Used to check that WaitForResult is only called once for each usage of the
|
| + // callback.
|
| + bool wait_for_result_called_;
|
| + // Indicates whether we have already been invoked.
|
| bool have_result_;
|
| + // The last result received (or PP_OK_COMPLETIONCALLBACK if none).
|
| int32_t result_;
|
| - bool force_async_;
|
| + CallbackType callback_type_;
|
| bool post_quit_task_;
|
| + std::string errors_;
|
| unsigned run_count_;
|
| PP_Instance instance_;
|
| };
|
|
|
| +// Verifies that the callback didn't record any errors. If the callback is run
|
| +// in an unexpected way (e.g., if it's invoked asynchronously when the call
|
| +// should have blocked), this returns an appropriate error string.
|
| +#define CHECK_CALLBACK_BEHAVIOR(callback) \
|
| +do { \
|
| + if ((callback).failed()) \
|
| + return (callback).errors(); \
|
| +} while (false)
|
| +
|
| /*
|
| * A set of macros to use for platform detection. These were largely copied
|
| * from chromium's build_config.h.
|
| @@ -71,7 +185,7 @@ class TestCompletionCallback {
|
| #elif defined(__sun)
|
| #define PPAPI_OS_SOLARIS 1
|
| #else
|
| -#error Please add support for your platform in ppapi/c/pp_macros.h.
|
| +#error Please add support for your platform in ppapi/tests/test_utils.h
|
| #endif
|
|
|
| /* These are used to determine POSIX-like implementations vs Windows. */
|
|
|