Home | History | Annotate | Download | only in functional
      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