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-SP hw path according to "ro.vndk.version" 48 #if defined(__LP64__) 49 std::string getVndkSpHwPath(const char* lib = "lib64"); 50 #else 51 std::string getVndkSpHwPath(const char* lib = "lib"); 52 #endif 53 54 // Explicitly invokes the parameterized element's destructor; 55 // intended to be used alongside the placement new operator. 56 template<typename T> 57 void destructElement(T* element) { 58 if (element != nullptr) { 59 element->~T(); 60 } 61 } 62 63 // HIDL client/server code should *NOT* use this class. 64 // 65 // hidl_pointer wraps a pointer without taking ownership, 66 // and stores it in a union with a uint64_t. This ensures 67 // that we always have enough space to store a pointer, 68 // regardless of whether we're running in a 32-bit or 64-bit 69 // process. 70 template<typename T> 71 struct hidl_pointer { 72 hidl_pointer() 73 : _pad(0) { 74 static_assert(sizeof(*this) == 8, "wrong size"); 75 } 76 hidl_pointer(T* ptr) : hidl_pointer() { mPointer = ptr; } 77 hidl_pointer(const hidl_pointer<T>& other) : hidl_pointer() { mPointer = other.mPointer; } 78 hidl_pointer(hidl_pointer<T>&& other) noexcept : hidl_pointer() { *this = std::move(other); } 79 80 hidl_pointer &operator=(const hidl_pointer<T>& other) { 81 mPointer = other.mPointer; 82 return *this; 83 } 84 hidl_pointer& operator=(hidl_pointer<T>&& other) noexcept { 85 mPointer = other.mPointer; 86 other.mPointer = nullptr; 87 return *this; 88 } 89 hidl_pointer &operator=(T* ptr) { 90 mPointer = ptr; 91 return *this; 92 } 93 94 operator T*() const { 95 return mPointer; 96 } 97 explicit operator void*() const { // requires explicit cast to avoid ambiguity 98 return mPointer; 99 } 100 T& operator*() const { 101 return *mPointer; 102 } 103 T* operator->() const { 104 return mPointer; 105 } 106 T &operator[](size_t index) { 107 return mPointer[index]; 108 } 109 const T &operator[](size_t index) const { 110 return mPointer[index]; 111 } 112 113 private: 114 union { 115 T* mPointer; 116 uint64_t _pad; 117 }; 118 }; 119 120 #define HAL_LIBRARY_PATH_SYSTEM_64BIT "/system/lib64/hw/" 121 #define HAL_LIBRARY_PATH_VENDOR_64BIT "/vendor/lib64/hw/" 122 #define HAL_LIBRARY_PATH_ODM_64BIT "/odm/lib64/hw/" 123 #define HAL_LIBRARY_PATH_SYSTEM_32BIT "/system/lib/hw/" 124 #define HAL_LIBRARY_PATH_VENDOR_32BIT "/vendor/lib/hw/" 125 #define HAL_LIBRARY_PATH_ODM_32BIT "/odm/lib/hw/" 126 127 #if defined(__LP64__) 128 #define HAL_LIBRARY_PATH_SYSTEM HAL_LIBRARY_PATH_SYSTEM_64BIT 129 #define HAL_LIBRARY_PATH_VENDOR HAL_LIBRARY_PATH_VENDOR_64BIT 130 #define HAL_LIBRARY_PATH_ODM HAL_LIBRARY_PATH_ODM_64BIT 131 #else 132 #define HAL_LIBRARY_PATH_SYSTEM HAL_LIBRARY_PATH_SYSTEM_32BIT 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 union { 205 bool mEnableInstrumentation; 206 void* mReserved0; 207 }; 208 // Prefix to lookup the instrumentation libraries. 209 std::string mInstrumentationLibPackage; 210 // Used for dlsym to load the profiling method for given interface. 211 std::string mInterfaceName; 212 213 }; 214 215 #ifdef __LP64__ 216 static_assert(sizeof(HidlInstrumentor) == 88, "HidlInstrumentor size frozen by prebuilts"); 217 #else 218 static_assert(sizeof(HidlInstrumentor) == 44, "HidlInstrumentor size frozen by prebuilts"); 219 #endif 220 221 } // namespace details 222 } // namespace hardware 223 } // namespace android 224 225 #endif // ANDROID_HIDL_INTERNAL_H 226