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 ANDROID_HIDL_INTERNAL_H 18 #define ANDROID_HIDL_INTERNAL_H 19 20 #include <cstdint> 21 #include <dirent.h> 22 #include <functional> 23 #include <string> 24 #include <vector> 25 #include <utility> 26 27 namespace android { 28 namespace hardware { 29 namespace details { 30 31 // tag for pure interfaces (e.x. IFoo) 32 struct i_tag {}; 33 34 // tag for server interfaces (e.x. BnHwFoo) 35 struct bnhw_tag {}; 36 37 // tag for proxy interfaces (e.x. BpHwFoo) 38 struct bphw_tag {}; 39 40 // tag for passthrough interfaces (e.x. BsFoo) 41 struct bs_tag {}; 42 43 //Templated classes can use the below method 44 //to avoid creating dependencies on liblog. 45 void logAlwaysFatal(const char *message); 46 47 // Returns vndk version from "ro.vndk.version" 48 std::string getVndkVersionStr(); 49 50 // Explicitly invokes the parameterized element's destructor; 51 // intended to be used alongside the placement new operator. 52 template<typename T> 53 void destructElement(T* element) { 54 if (element != nullptr) { 55 element->~T(); 56 } 57 } 58 59 // HIDL client/server code should *NOT* use this class. 60 // 61 // hidl_pointer wraps a pointer without taking ownership, 62 // and stores it in a union with a uint64_t. This ensures 63 // that we always have enough space to store a pointer, 64 // regardless of whether we're running in a 32-bit or 64-bit 65 // process. 66 template<typename T> 67 struct hidl_pointer { 68 hidl_pointer() 69 : _pad(0) { 70 static_assert(sizeof(*this) == 8, "wrong size"); 71 } 72 hidl_pointer(T* ptr) : hidl_pointer() { mPointer = ptr; } 73 hidl_pointer(const hidl_pointer<T>& other) : hidl_pointer() { mPointer = other.mPointer; } 74 hidl_pointer(hidl_pointer<T>&& other) noexcept : hidl_pointer() { *this = std::move(other); } 75 76 hidl_pointer &operator=(const hidl_pointer<T>& other) { 77 mPointer = other.mPointer; 78 return *this; 79 } 80 hidl_pointer& operator=(hidl_pointer<T>&& other) noexcept { 81 mPointer = other.mPointer; 82 other.mPointer = nullptr; 83 return *this; 84 } 85 hidl_pointer &operator=(T* ptr) { 86 mPointer = ptr; 87 return *this; 88 } 89 90 operator T*() const { 91 return mPointer; 92 } 93 explicit operator void*() const { // requires explicit cast to avoid ambiguity 94 return mPointer; 95 } 96 T& operator*() const { 97 return *mPointer; 98 } 99 T* operator->() const { 100 return mPointer; 101 } 102 T &operator[](size_t index) { 103 return mPointer[index]; 104 } 105 const T &operator[](size_t index) const { 106 return mPointer[index]; 107 } 108 109 private: 110 union { 111 T* mPointer; 112 uint64_t _pad; 113 }; 114 }; 115 116 #define HAL_LIBRARY_PATH_SYSTEM_64BIT "/system/lib64/hw/" 117 #define HAL_LIBRARY_PATH_VNDK_SP_64BIT_FOR_VERSION "/apex/com.android.vndk.v%s/lib64/hw/" 118 #define HAL_LIBRARY_PATH_VENDOR_64BIT "/vendor/lib64/hw/" 119 #define HAL_LIBRARY_PATH_ODM_64BIT "/odm/lib64/hw/" 120 #define HAL_LIBRARY_PATH_SYSTEM_32BIT "/system/lib/hw/" 121 #define HAL_LIBRARY_PATH_VNDK_SP_32BIT_FOR_VERSION "/apex/com.android.vndk.v%s/lib/hw/" 122 #define HAL_LIBRARY_PATH_VENDOR_32BIT "/vendor/lib/hw/" 123 #define HAL_LIBRARY_PATH_ODM_32BIT "/odm/lib/hw/" 124 125 #if defined(__LP64__) 126 #define HAL_LIBRARY_PATH_SYSTEM HAL_LIBRARY_PATH_SYSTEM_64BIT 127 #define HAL_LIBRARY_PATH_VNDK_SP_FOR_VERSION HAL_LIBRARY_PATH_VNDK_SP_64BIT_FOR_VERSION 128 #define HAL_LIBRARY_PATH_VENDOR HAL_LIBRARY_PATH_VENDOR_64BIT 129 #define HAL_LIBRARY_PATH_ODM HAL_LIBRARY_PATH_ODM_64BIT 130 #else 131 #define HAL_LIBRARY_PATH_SYSTEM HAL_LIBRARY_PATH_SYSTEM_32BIT 132 #define HAL_LIBRARY_PATH_VNDK_SP_FOR_VERSION HAL_LIBRARY_PATH_VNDK_SP_32BIT_FOR_VERSION 133 #define HAL_LIBRARY_PATH_VENDOR HAL_LIBRARY_PATH_VENDOR_32BIT 134 #define HAL_LIBRARY_PATH_ODM HAL_LIBRARY_PATH_ODM_32BIT 135 #endif 136 137 // ---------------------------------------------------------------------- 138 // Class that provides Hidl instrumentation utilities. 139 struct HidlInstrumentor { 140 // Event that triggers the instrumentation. e.g. enter of an API call on 141 // the server/client side, exit of an API call on the server/client side 142 // etc. 143 enum InstrumentationEvent { 144 SERVER_API_ENTRY = 0, 145 SERVER_API_EXIT, 146 CLIENT_API_ENTRY, 147 CLIENT_API_EXIT, 148 SYNC_CALLBACK_ENTRY, 149 SYNC_CALLBACK_EXIT, 150 ASYNC_CALLBACK_ENTRY, 151 ASYNC_CALLBACK_EXIT, 152 PASSTHROUGH_ENTRY, 153 PASSTHROUGH_EXIT, 154 }; 155 156 // Signature of the instrumentation callback function. 157 using InstrumentationCallback = std::function<void( 158 const InstrumentationEvent event, 159 const char *package, 160 const char *version, 161 const char *interface, 162 const char *method, 163 std::vector<void *> *args)>; 164 165 explicit HidlInstrumentor( 166 const std::string &package, 167 const std::string &insterface); 168 virtual ~HidlInstrumentor(); 169 170 public: 171 const std::vector<InstrumentationCallback>& getInstrumentationCallbacks() { 172 return mInstrumentationCallbacks; 173 } 174 bool isInstrumentationEnabled() { return mEnableInstrumentation; } 175 176 protected: 177 // Set mEnableInstrumentation based on system property 178 // hal.instrumentation.enable, register/de-register instrumentation 179 // callbacks if mEnableInstrumentation is true/false. 180 void configureInstrumentation(bool log=true); 181 // Function that lookup and dynamically loads the hidl instrumentation 182 // libraries and registers the instrumentation callback functions. 183 // 184 // The instrumentation libraries should be stored under any of the following 185 // directories: HAL_LIBRARY_PATH_SYSTEM, HAL_LIBRARY_PATH_VNDK_SP, 186 // HAL_LIBRARY_PATH_VENDOR and HAL_LIBRARY_PATH_ODM. 187 // The name of instrumentation libraries should follow pattern: 188 // ^profilerPrefix(.*).profiler.so$ 189 // 190 // Each instrumentation library is expected to implement the instrumentation 191 // function called HIDL_INSTRUMENTATION_FUNCTION. 192 // 193 // A no-op for user build. 194 void registerInstrumentationCallbacks( 195 std::vector<InstrumentationCallback> *instrumentationCallbacks); 196 197 // Utility function to determine whether a give file is a instrumentation 198 // library (i.e. the file name follow the expected pattern). 199 bool isInstrumentationLib(const dirent *file); 200 201 // A list of registered instrumentation callbacks. 202 std::vector<InstrumentationCallback> mInstrumentationCallbacks; 203 // Flag whether to enable instrumentation. 204 bool mEnableInstrumentation; 205 // Prefix to lookup the instrumentation libraries. 206 std::string mInstrumentationLibPackage; 207 // Used for dlsym to load the profiling method for given interface. 208 std::string mInterfaceName; 209 210 }; 211 212 } // namespace details 213 } // namespace hardware 214 } // namespace android 215 216 #endif // ANDROID_HIDL_INTERNAL_H 217