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_3 {
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>
validateAndCall(ObjT * obj,WifiStatusCode status_code_if_invalid,WorkFuncT && work,const std::function<void (const WifiStatus &)> & hidl_cb,Args &&...args)43 Return<void> validateAndCall(
44 ObjT* obj, WifiStatusCode status_code_if_invalid, WorkFuncT&& work,
45 const std::function<void(const WifiStatus&)>& hidl_cb, Args&&... args) {
46 const auto lock = hidl_sync_util::acquireGlobalLock();
47 if (obj->isValid()) {
48 hidl_cb((obj->*work)(std::forward<Args>(args)...));
49 } else {
50 hidl_cb(createWifiStatus(status_code_if_invalid));
51 }
52 return Void();
53 }
54
55 // Use for HIDL methods which return only an instance of WifiStatus.
56 // This version passes the global lock acquired to the body of the method.
57 // Note: Only used by IWifi::stop() currently.
58 template <typename ObjT, typename WorkFuncT, typename... Args>
validateAndCallWithLock(ObjT * obj,WifiStatusCode status_code_if_invalid,WorkFuncT && work,const std::function<void (const WifiStatus &)> & hidl_cb,Args &&...args)59 Return<void> validateAndCallWithLock(
60 ObjT* obj, WifiStatusCode status_code_if_invalid, WorkFuncT&& work,
61 const std::function<void(const WifiStatus&)>& hidl_cb, Args&&... args) {
62 auto lock = hidl_sync_util::acquireGlobalLock();
63 if (obj->isValid()) {
64 hidl_cb((obj->*work)(&lock, std::forward<Args>(args)...));
65 } else {
66 hidl_cb(createWifiStatus(status_code_if_invalid));
67 }
68 return Void();
69 }
70
71 // Use for HIDL methods which return instance of WifiStatus and a single return
72 // value.
73 template <typename ObjT, typename WorkFuncT, typename ReturnT, typename... Args>
validateAndCall(ObjT * obj,WifiStatusCode status_code_if_invalid,WorkFuncT && work,const std::function<void (const WifiStatus &,ReturnT)> & hidl_cb,Args &&...args)74 Return<void> validateAndCall(
75 ObjT* obj, WifiStatusCode status_code_if_invalid, WorkFuncT&& work,
76 const std::function<void(const WifiStatus&, ReturnT)>& hidl_cb,
77 Args&&... args) {
78 const auto lock = hidl_sync_util::acquireGlobalLock();
79 if (obj->isValid()) {
80 const auto& ret_pair = (obj->*work)(std::forward<Args>(args)...);
81 const WifiStatus& status = std::get<0>(ret_pair);
82 const auto& ret_value = std::get<1>(ret_pair);
83 hidl_cb(status, ret_value);
84 } else {
85 hidl_cb(createWifiStatus(status_code_if_invalid),
86 typename std::remove_reference<ReturnT>::type());
87 }
88 return Void();
89 }
90
91 // Use for HIDL methods which return instance of WifiStatus and 2 return
92 // values.
93 template <typename ObjT, typename WorkFuncT, typename ReturnT1,
94 typename ReturnT2, typename... Args>
validateAndCall(ObjT * obj,WifiStatusCode status_code_if_invalid,WorkFuncT && work,const std::function<void (const WifiStatus &,ReturnT1,ReturnT2)> & hidl_cb,Args &&...args)95 Return<void> validateAndCall(
96 ObjT* obj, WifiStatusCode status_code_if_invalid, WorkFuncT&& work,
97 const std::function<void(const WifiStatus&, ReturnT1, ReturnT2)>& hidl_cb,
98 Args&&... args) {
99 const auto lock = hidl_sync_util::acquireGlobalLock();
100 if (obj->isValid()) {
101 const auto& ret_tuple = (obj->*work)(std::forward<Args>(args)...);
102 const WifiStatus& status = std::get<0>(ret_tuple);
103 const auto& ret_value1 = std::get<1>(ret_tuple);
104 const auto& ret_value2 = std::get<2>(ret_tuple);
105 hidl_cb(status, ret_value1, ret_value2);
106 } else {
107 hidl_cb(createWifiStatus(status_code_if_invalid),
108 typename std::remove_reference<ReturnT1>::type(),
109 typename std::remove_reference<ReturnT2>::type());
110 }
111 return Void();
112 }
113
114 } // namespace hidl_return_util
115 } // namespace implementation
116 } // namespace V1_3
117 } // namespace wifi
118 } // namespace hardware
119 } // namespace android
120 #endif // HIDL_RETURN_UTIL_H_
121