event_utils_winrt.h 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. // Copyright 2018 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 DEVICE_BLUETOOTH_EVENT_UTILS_WINRT_H_
  5. #define DEVICE_BLUETOOTH_EVENT_UTILS_WINRT_H_
  6. #include <windows.foundation.h>
  7. #include <wrl/client.h>
  8. #include <wrl/event.h>
  9. #include <type_traits>
  10. #include <utility>
  11. #include "base/bind.h"
  12. #include "base/logging.h"
  13. #include "base/memory/ref_counted.h"
  14. #include "base/threading/thread_task_runner_handle.h"
  15. #include "third_party/abseil-cpp/absl/types/optional.h"
  16. namespace device {
  17. namespace internal {
  18. template <typename Interface, typename... Args>
  19. using IMemberFunction = HRESULT (__stdcall Interface::*)(Args...);
  20. } // namespace internal
  21. // Convenience template function to construct a TypedEventHandler from a
  22. // base::RepeatingCallback of a matching signature. In case of success, the
  23. // EventRegistrationToken is returned to the caller. A return value of
  24. // absl::nullopt indicates a failure. Events are posted to the same thread the
  25. // event handler was created on.
  26. template <typename Interface,
  27. typename Sender,
  28. typename Args,
  29. typename SenderAbi,
  30. typename ArgsAbi>
  31. absl::optional<EventRegistrationToken> AddTypedEventHandler(
  32. Interface* i,
  33. internal::IMemberFunction<
  34. Interface,
  35. ABI::Windows::Foundation::ITypedEventHandler<Sender*, Args*>*,
  36. EventRegistrationToken*> function,
  37. base::RepeatingCallback<void(SenderAbi*, ArgsAbi*)> callback) {
  38. EventRegistrationToken token;
  39. HRESULT hr = ((*i).*function)(
  40. Microsoft::WRL::Callback<ABI::Windows::Foundation::ITypedEventHandler<
  41. Sender*, Args*>>([task_runner(base::ThreadTaskRunnerHandle::Get()),
  42. callback(std::move(callback))](SenderAbi* sender,
  43. ArgsAbi* args) {
  44. // Make sure we are still on the same thread.
  45. DCHECK_EQ(base::ThreadTaskRunnerHandle::Get(), task_runner);
  46. task_runner->PostTask(
  47. FROM_HERE,
  48. base::BindOnce(callback, Microsoft::WRL::ComPtr<SenderAbi>(sender),
  49. Microsoft::WRL::ComPtr<ArgsAbi>(args)));
  50. return S_OK;
  51. }).Get(),
  52. &token);
  53. if (FAILED(hr)) {
  54. DVLOG(2) << "Adding EventHandler failed: "
  55. << logging::SystemErrorCodeToString(hr);
  56. return absl::nullopt;
  57. }
  58. return token;
  59. }
  60. } // namespace device
  61. #endif // DEVICE_BLUETOOTH_EVENT_UTILS_WINRT_H_