// Copyright 2018 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. #ifndef DEVICE_BLUETOOTH_EVENT_UTILS_WINRT_H_ #define DEVICE_BLUETOOTH_EVENT_UTILS_WINRT_H_ #include #include #include #include #include #include "base/bind.h" #include "base/logging.h" #include "base/memory/ref_counted.h" #include "base/optional.h" #include "base/threading/thread_task_runner_handle.h" namespace device { namespace internal { template using IMemberFunction = HRESULT (__stdcall Interface::*)(Args...); } // namespace internal // Convenience template function to construct a TypedEventHandler from a // base::RepeatingCallback of a matching signature. In case of success, the // EventRegistrationToken is returned to the caller. A return value of // base::nullopt indicates a failure. Events are posted to the same thread the // event handler was created on. template base::Optional AddTypedEventHandler( Interface* i, internal::IMemberFunction< Interface, ABI::Windows::Foundation::ITypedEventHandler*, EventRegistrationToken*> function, base::RepeatingCallback callback) { EventRegistrationToken token; HRESULT hr = ((*i).*function)( Microsoft::WRL::Callback>([task_runner(base::ThreadTaskRunnerHandle::Get()), callback(std::move(callback))](SenderAbi* sender, ArgsAbi* args) { // Make sure we are still on the same thread. DCHECK_EQ(base::ThreadTaskRunnerHandle::Get(), task_runner); task_runner->PostTask( FROM_HERE, base::BindOnce(callback, Microsoft::WRL::ComPtr(sender), Microsoft::WRL::ComPtr(args))); return S_OK; }).Get(), &token); if (FAILED(hr)) { DVLOG(2) << "Adding EventHandler failed: " << logging::SystemErrorCodeToString(hr); return base::nullopt; } return token; } } // namespace device #endif // DEVICE_BLUETOOTH_EVENT_UTILS_WINRT_H_