1 /* 2 * Copyright (C) 2017 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 #include <functional> 18 #include <type_traits> 19 20 #include <hidl/Status.h> 21 #include <utils/RefBase.h> 22 #include <utils/StrongPointer.h> 23 24 #include "wifi_hidl_call_util.h" 25 26 namespace { 27 /* 28 * Example of a user-defined data-type. 29 * 30 * Used to verify that, within the internals of HIDL_INVOKE, 31 * reference parameters are stored by copy. 32 */ 33 class Dummy {}; 34 35 /* 36 * Example of what a HIDL-generated proxy might look like. 37 */ 38 class IExample : public ::android::RefBase { 39 public: 40 // The callback type, for a method called startWithCallbackCopy, which 41 // has a callback that takes an |int|. Both the name, and the value, 42 // must match what would appear in HIDL-generated code. 43 using startWithCallbackCopy_cb = std::function<void(int)>; 44 45 // The callback type, for a method called startWithCallbackReference, which 46 // has a callback that takes an |int|. Both the name, and the value, 47 // must match what would appear in HIDL-generated code. 48 using startWithCallbackReference_cb = std::function<void(int)>; 49 50 // Constants which allow tests to verify that the proxy methods can 51 // correctly return a value. We use different values for by-copy and 52 // by-reference, to double-check that a call was dispatched properly. 53 static constexpr int kByCopyResult = 42; 54 static constexpr int kByReferenceResult = 420; 55 56 // Example of what a no-arg method would look like, if the callback 57 // is passed by-value. 58 ::android::hardware::Return<void> startWithCallbackCopy( 59 startWithCallbackCopy_cb _hidl_cb) { 60 _hidl_cb(kByCopyResult); 61 return ::android::hardware::Void(); 62 } 63 // Example of what a no-arg method would look like, if the callback 64 // is passed by const-reference. 65 ::android::hardware::Return<void> startWithCallbackReference( 66 const startWithCallbackReference_cb& _hidl_cb) { 67 _hidl_cb(kByReferenceResult); 68 return ::android::hardware::Void(); 69 } 70 }; 71 72 constexpr int IExample::kByCopyResult; 73 constexpr int IExample::kByReferenceResult; 74 } // namespace 75 76 static_assert(std::is_same<int, detail::functionArgSaver< 77 std::function<void(int)>>::StorageT>::value, 78 "Single-arg result should be stored directly."); 79 80 static_assert( 81 std::is_same<std::pair<int, long>, detail::functionArgSaver<std::function< 82 void(int, long)>>::StorageT>::value, 83 "Two-arg result should be stored as a pair."); 84 85 static_assert( 86 std::is_same<std::tuple<char, int, long>, 87 detail::functionArgSaver< 88 std::function<void(char, int, long)>>::StorageT>::value, 89 "Three-arg result should be stored as a tuple."); 90 91 static_assert(std::is_same<Dummy, detail::functionArgSaver<std::function< 92 void(const Dummy&)>>::StorageT>::value, 93 "Reference should be stored by copy."); 94 95 /* 96 * Verifies that HIDL_INVOKE can be used with methods that take the result 97 * callback as a by-value parameter. (This reflects the current implementation 98 * of HIDL-generated code.) 99 */ 100 TEST(HidlInvokeTest, WorksWithMethodThatTakesResultCallbackByValue) { 101 ::android::sp<IExample> sp = new IExample(); 102 EXPECT_EQ(IExample::kByCopyResult, HIDL_INVOKE(sp, startWithCallbackCopy)); 103 } 104 105 /* 106 * Verifies that HIDL_INVOKE can be used with methods that take the result 107 * callback as a const-reference parameter. (This ensures that HIDL_INVOKE will 108 * continue to work, if the HIDL-generated code switches to const-ref.) 109 */ 110 TEST(HidlInvokeTest, WorksWithMethodThatTakesResultCallbackByConstReference) { 111 ::android::sp<IExample> sp = new IExample(); 112 EXPECT_EQ(IExample::kByReferenceResult, 113 HIDL_INVOKE(sp, startWithCallbackReference)); 114 } 115