1 /* 2 * Copyright (C) 2016 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 #ifndef HIDL_RETURN_UTIL_H_ 18 #define HIDL_RETURN_UTIL_H_ 19 20 #include "hidl_sync_util.h" 21 #include "wifi_status_util.h" 22 23 namespace android { 24 namespace hardware { 25 namespace wifi { 26 namespace V1_1 { 27 namespace implementation { 28 namespace hidl_return_util { 29 using namespace android::hardware::wifi::V1_0; 30 31 /** 32 * These utility functions are used to invoke a method on the provided 33 * HIDL interface object. 34 * These functions checks if the provided HIDL interface object is valid. 35 * a) if valid, Invokes the corresponding internal implementation function of 36 * the HIDL method. It then invokes the HIDL continuation callback with 37 * the status and any returned values. 38 * b) if invalid, invokes the HIDL continuation callback with the 39 * provided error status and default values. 40 */ 41 // Use for HIDL methods which return only an instance of WifiStatus. 42 template <typename ObjT, typename WorkFuncT, typename... Args> 43 Return<void> validateAndCall( 44 ObjT* obj, 45 WifiStatusCode status_code_if_invalid, 46 WorkFuncT&& work, 47 const std::function<void(const WifiStatus&)>& hidl_cb, 48 Args&&... args) { 49 const auto lock = hidl_sync_util::acquireGlobalLock(); 50 if (obj->isValid()) { 51 hidl_cb((obj->*work)(std::forward<Args>(args)...)); 52 } else { 53 hidl_cb(createWifiStatus(status_code_if_invalid)); 54 } 55 return Void(); 56 } 57 58 // Use for HIDL methods which return only an instance of WifiStatus. 59 // This version passes the global lock acquired to the body of the method. 60 // Note: Only used by IWifi::stop() currently. 61 template <typename ObjT, typename WorkFuncT, typename... Args> 62 Return<void> validateAndCallWithLock( 63 ObjT* obj, 64 WifiStatusCode status_code_if_invalid, 65 WorkFuncT&& work, 66 const std::function<void(const WifiStatus&)>& hidl_cb, 67 Args&&... args) { 68 auto lock = hidl_sync_util::acquireGlobalLock(); 69 if (obj->isValid()) { 70 hidl_cb((obj->*work)(&lock, std::forward<Args>(args)...)); 71 } else { 72 hidl_cb(createWifiStatus(status_code_if_invalid)); 73 } 74 return Void(); 75 } 76 77 // Use for HIDL methods which return instance of WifiStatus and a single return 78 // value. 79 template <typename ObjT, typename WorkFuncT, typename ReturnT, typename... Args> 80 Return<void> validateAndCall( 81 ObjT* obj, 82 WifiStatusCode status_code_if_invalid, 83 WorkFuncT&& work, 84 const std::function<void(const WifiStatus&, ReturnT)>& hidl_cb, 85 Args&&... args) { 86 const auto lock = hidl_sync_util::acquireGlobalLock(); 87 if (obj->isValid()) { 88 const auto& ret_pair = (obj->*work)(std::forward<Args>(args)...); 89 const WifiStatus& status = std::get<0>(ret_pair); 90 const auto& ret_value = std::get<1>(ret_pair); 91 hidl_cb(status, ret_value); 92 } else { 93 hidl_cb(createWifiStatus(status_code_if_invalid), 94 typename std::remove_reference<ReturnT>::type()); 95 } 96 return Void(); 97 } 98 99 // Use for HIDL methods which return instance of WifiStatus and 2 return 100 // values. 101 template <typename ObjT, 102 typename WorkFuncT, 103 typename ReturnT1, 104 typename ReturnT2, 105 typename... Args> 106 Return<void> validateAndCall( 107 ObjT* obj, 108 WifiStatusCode status_code_if_invalid, 109 WorkFuncT&& work, 110 const std::function<void(const WifiStatus&, ReturnT1, ReturnT2)>& hidl_cb, 111 Args&&... args) { 112 const auto lock = hidl_sync_util::acquireGlobalLock(); 113 if (obj->isValid()) { 114 const auto& ret_tuple = (obj->*work)(std::forward<Args>(args)...); 115 const WifiStatus& status = std::get<0>(ret_tuple); 116 const auto& ret_value1 = std::get<1>(ret_tuple); 117 const auto& ret_value2 = std::get<2>(ret_tuple); 118 hidl_cb(status, ret_value1, ret_value2); 119 } else { 120 hidl_cb(createWifiStatus(status_code_if_invalid), 121 typename std::remove_reference<ReturnT1>::type(), 122 typename std::remove_reference<ReturnT2>::type()); 123 } 124 return Void(); 125 } 126 127 } // namespace hidl_util 128 } // namespace implementation 129 } // namespace V1_1 130 } // namespace wifi 131 } // namespace hardware 132 } // namespace android 133 #endif // HIDL_RETURN_UTIL_H_ 134