• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2018 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 // This file is copied from
18 // hardware/interfaces/wifi/1.0/vts/functional/wifi_hidl_call_util.h
19 // Please make sure these two file are consistent.
20 
21 #pragma once
22 
23 #include <functional>
24 #include <tuple>
25 #include <type_traits>
26 #include <utility>
27 
28 #include <VtsHalHidlTargetTestBase.h>
29 
30 namespace {
31 namespace detail {
32 template <typename>
33 struct functionArgSaver;
34 
35 // Provides a std::function that takes one argument, and a buffer
36 // wherein the function will store its argument. The buffer has
37 // the same type as the argument, but with const and reference
38 // modifiers removed.
39 template <typename ArgT>
40 struct functionArgSaver<std::function<void(ArgT)>> final {
41     using StorageT = typename std::remove_const<
42         typename std::remove_reference<ArgT>::type>::type;
43 
44     std::function<void(ArgT)> saveArgs = [this](ArgT arg) {
45         this->saved_values = arg;
46     };
47 
48     StorageT saved_values;
49 };
50 
51 // Provides a std::function that takes two arguments, and a buffer
52 // wherein the function will store its arguments. The buffer is a
53 // std::pair, whose elements have the same types as the arguments
54 // (but with const and reference modifiers removed).
55 template <typename Arg1T, typename Arg2T>
56 struct functionArgSaver<std::function<void(Arg1T, Arg2T)>> final {
57     using StorageT =
58         std::pair<typename std::remove_const<
59                       typename std::remove_reference<Arg1T>::type>::type,
60                   typename std::remove_const<
61                       typename std::remove_reference<Arg2T>::type>::type>;
62 
63     std::function<void(Arg1T, Arg2T)> saveArgs = [this](Arg1T arg1,
64                                                         Arg2T arg2) {
65         this->saved_values = {arg1, arg2};
66     };
67 
68     StorageT saved_values;
69 };
70 
71 // Provides a std::function that takes three or more arguments, and a
72 // buffer wherein the function will store its arguments. The buffer is a
73 // std::tuple whose elements have the same types as the arguments (but
74 // with const and reference modifiers removed).
75 template <typename... ArgT>
76 struct functionArgSaver<std::function<void(ArgT...)>> final {
77     using StorageT = std::tuple<typename std::remove_const<
78         typename std::remove_reference<ArgT>::type>::type...>;
79 
80     std::function<void(ArgT...)> saveArgs = [this](ArgT... arg) {
81         this->saved_values = {arg...};
82     };
83 
84     StorageT saved_values;
85 };
86 
87 // Invokes |method| on |object|, providing |method| a CallbackT as the
88 // final argument. Returns a copy of the parameters that |method| provided
89 // to CallbackT. (The parameters are returned by value.)
90 template <typename CallbackT, typename MethodT, typename ObjectT,
91           typename... ArgT>
92 typename functionArgSaver<CallbackT>::StorageT invokeMethod(
93     MethodT method, ObjectT object, ArgT&&... methodArg) {
94     functionArgSaver<CallbackT> result_buffer;
95     const auto& res = ((*object).*method)(std::forward<ArgT>(methodArg)...,
96                                           result_buffer.saveArgs);
97     EXPECT_TRUE(res.isOk());
98     return result_buffer.saved_values;
99 }
100 }  // namespace detail
101 }  // namespace
102 
103 // Invokes |method| on |strong_pointer|, passing provided arguments through to
104 // |method|.
105 //
106 // Returns either:
107 // - A copy of the result callback parameter (for callbacks with a single
108 //   parameter), OR
109 // - A pair containing a copy of the result callback parameters (for callbacks
110 //   with two parameters), OR
111 // - A tuple containing a copy of the result callback paramters (for callbacks
112 //   with three or more parameters).
113 //
114 // Example usage:
115 //   EXPECT_EQ(HostapdStatusCode::SUCCESS,
116 //       HIDL_INVOKE(strong_pointer, methodReturningHostapdStatus).code);
117 //   EXPECT_EQ(HostapdStatusCode::SUCCESS,
118 //       HIDL_INVOKE(strong_pointer, methodReturningHostapdStatusAndOneMore)
119 //         .first.code);
120 //   EXPECT_EQ(HostapdStatusCode::SUCCESS, std::get<0>(
121 //       HIDL_INVOKE(strong_pointer, methodReturningHostapdStatusAndTwoMore))
122 //         .code);
123 #define HIDL_INVOKE(strong_pointer, method, ...)                              \
124     (detail::invokeMethod<                                                    \
125         std::remove_reference<decltype(*strong_pointer)>::type::method##_cb>( \
126         &std::remove_reference<decltype(*strong_pointer)>::type::method,      \
127         strong_pointer, ##__VA_ARGS__))
128