fake_iasync_operation_win.h 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. // Copyright 2020 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #ifndef BASE_TEST_FAKE_IASYNC_OPERATION_WIN_H_
  5. #define BASE_TEST_FAKE_IASYNC_OPERATION_WIN_H_
  6. #include <wrl/client.h>
  7. #include "base/notreached.h"
  8. #include "base/win/winrt_foundation_helpers.h"
  9. #include "testing/gtest/include/gtest/gtest.h"
  10. namespace base {
  11. namespace win {
  12. namespace internal {
  13. // Templates used to allow easy reference to the correct types.
  14. // See base/win/winrt_foundation_helpers.h for explanation.
  15. template <typename T>
  16. using AsyncOperationComplex =
  17. typename ABI::Windows::Foundation::IAsyncOperation<T>::TResult_complex;
  18. template <typename T>
  19. using AsyncOperationAbi = AbiType<AsyncOperationComplex<T>>;
  20. template <typename T>
  21. using AsyncOperationOptionalStorage =
  22. OptionalStorageType<AsyncOperationComplex<T>>;
  23. template <typename T>
  24. using AsyncOperationStorage = StorageType<AsyncOperationComplex<T>>;
  25. } // namespace internal
  26. // Provides an implementation of Windows::Foundation::IAsyncOperation for
  27. // use in GTests.
  28. template <typename T>
  29. class FakeIAsyncOperation final
  30. : public Microsoft::WRL::RuntimeClass<
  31. Microsoft::WRL::RuntimeClassFlags<
  32. Microsoft::WRL::WinRt | Microsoft::WRL::InhibitRoOriginateError>,
  33. ABI::Windows::Foundation::IAsyncOperation<T>,
  34. ABI::Windows::Foundation::IAsyncInfo> {
  35. public:
  36. FakeIAsyncOperation() = default;
  37. FakeIAsyncOperation(const FakeIAsyncOperation&) = delete;
  38. FakeIAsyncOperation& operator=(const FakeIAsyncOperation&) = delete;
  39. // ABI::Windows::Foundation::IAsyncOperation:
  40. IFACEMETHODIMP put_Completed(
  41. ABI::Windows::Foundation::IAsyncOperationCompletedHandler<T>* handler)
  42. final {
  43. EXPECT_EQ(nullptr, handler_)
  44. << "put_Completed called on IAsyncOperation with a CompletedHandler "
  45. "already defined.";
  46. handler_ = handler;
  47. return S_OK;
  48. }
  49. IFACEMETHODIMP get_Completed(
  50. ABI::Windows::Foundation::IAsyncOperationCompletedHandler<T>** handler)
  51. final {
  52. NOTREACHED();
  53. return E_NOTIMPL;
  54. }
  55. IFACEMETHODIMP GetResults(internal::AsyncOperationAbi<T>* results) final {
  56. if (!is_complete_) {
  57. ADD_FAILURE() << "GetResults called on incomplete IAsyncOperation.";
  58. return E_PENDING;
  59. }
  60. if (status_ != AsyncStatus::Completed)
  61. return E_UNEXPECTED;
  62. return base::win::internal::CopyTo(results_, results);
  63. }
  64. // ABI::Windows::Foundation::IAsyncInfo:
  65. IFACEMETHODIMP get_Id(uint32_t* id) final {
  66. NOTREACHED();
  67. return E_NOTIMPL;
  68. }
  69. IFACEMETHODIMP get_Status(AsyncStatus* status) final {
  70. *status = status_;
  71. return S_OK;
  72. }
  73. IFACEMETHODIMP get_ErrorCode(HRESULT* error_code) final {
  74. *error_code = error_code_;
  75. return S_OK;
  76. }
  77. IFACEMETHODIMP Cancel() final {
  78. NOTREACHED();
  79. return E_NOTIMPL;
  80. }
  81. IFACEMETHODIMP Close() final {
  82. NOTREACHED();
  83. return E_NOTIMPL;
  84. }
  85. // Completes the operation with |error_code|.
  86. //
  87. // The get_ErrorCode API will be set to return |error_code|, the remainder of
  88. // the APIs will be set to represent an error state, and the CompletedHandler
  89. // (if defined) will be run.
  90. void CompleteWithError(HRESULT error_code) {
  91. error_code_ = error_code;
  92. status_ = AsyncStatus::Error;
  93. InvokeCompletedHandler();
  94. }
  95. // Completes the operation with |results|.
  96. //
  97. // The GetResults API will be set to return |results|, the remainder of the
  98. // APIs will be set to represent a successfully completed state, and the
  99. // CompletedHandler (if defined) will be run.
  100. void CompleteWithResults(internal::AsyncOperationStorage<T> results) {
  101. error_code_ = S_OK;
  102. results_ = std::move(results);
  103. status_ = AsyncStatus::Completed;
  104. InvokeCompletedHandler();
  105. }
  106. private:
  107. void InvokeCompletedHandler() {
  108. ASSERT_FALSE(is_complete_)
  109. << "Attempted to invoke completion on an already "
  110. "completed IAsyncOperation.";
  111. is_complete_ = true;
  112. if (handler_)
  113. handler_->Invoke(this, status_);
  114. }
  115. HRESULT error_code_ = S_OK;
  116. Microsoft::WRL::ComPtr<
  117. ABI::Windows::Foundation::IAsyncOperationCompletedHandler<T>>
  118. handler_;
  119. bool is_complete_ = false;
  120. internal::AsyncOperationOptionalStorage<T> results_;
  121. AsyncStatus status_ = AsyncStatus::Started;
  122. };
  123. } // namespace win
  124. } // namespace base
  125. #endif // BASE_TEST_FAKE_IASYNC_OPERATION_WIN_H_