1 /* 2 * Copyright (C) 2022 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 DISPLAY_COLOR_LOADER_H 18 #define DISPLAY_COLOR_LOADER_H 19 20 #include <dlfcn.h> 21 #include <log/log.h> 22 #include <string> 23 #include <vector> 24 25 template <typename GsInterfaceType, const char *entry> 26 class DisplayColorLoader { 27 static_assert(entry != nullptr); 28 public: 29 DisplayColorLoader(const DisplayColorLoader &) = delete; 30 DisplayColorLoader& operator=(const DisplayColorLoader &) = delete; 31 DisplayColorLoader(const std::string & libName)32 DisplayColorLoader(const std::string &libName) { 33 libHandle = dlopen(libName.c_str(), RTLD_LAZY); 34 35 if (libHandle == nullptr) { 36 ALOGE("%s: failed to load library %s\n", __func__, libName.c_str()); 37 getDisplayColor = nullptr; 38 return; 39 } 40 41 const displaycolor::DisplayColorIntfVer *(*getVersion)(); 42 getVersion = reinterpret_cast<decltype(getVersion)>(dlsym(libHandle, "GetInterfaceVersion")); 43 if (getVersion == nullptr) { 44 ALOGE("%s: prebuilt lib is not versioned", __func__); 45 return; 46 } 47 48 auto intfVer = getVersion(); 49 50 if (intfVer != nullptr && 51 displaycolor::kInterfaceVersion.Compatible(*intfVer)) { 52 getDisplayColor = reinterpret_cast<decltype(getDisplayColor)>(dlsym(libHandle, entry)); 53 54 if (getDisplayColor == nullptr) { 55 ALOGE("%s: failed to get %s\n", __func__, entry); 56 } else if (!(displaycolor::kInterfaceVersion == *intfVer)) { 57 ALOGW("%s: different hwc/displaycolor patch level %u.%u.%u vs .%u", 58 __func__, 59 intfVer->major, 60 intfVer->minor, 61 displaycolor::kInterfaceVersion.patch, 62 intfVer->patch); 63 } 64 } else { 65 if (intfVer != nullptr) { 66 ALOGE("%s: prebuilt lib version %u.%u.%u expected %u.%u.%u", 67 __func__, 68 intfVer->major, 69 intfVer->minor, 70 intfVer->patch, 71 displaycolor::kInterfaceVersion.major, 72 displaycolor::kInterfaceVersion.minor, 73 displaycolor::kInterfaceVersion.patch); 74 } else { 75 ALOGE("%s: prebult lib getVersion returns null", __func__); 76 } 77 } 78 } 79 GetDisplayColor(const std::vector<displaycolor::DisplayInfo> & display_info)80 GsInterfaceType *GetDisplayColor( 81 const std::vector<displaycolor::DisplayInfo> &display_info) { 82 if (getDisplayColor != nullptr) { 83 return getDisplayColor(display_info); 84 } 85 86 return nullptr; 87 } 88 ~DisplayColorLoader()89 ~DisplayColorLoader() { 90 if (libHandle != nullptr) { 91 dlclose(libHandle); 92 } 93 } 94 95 private: 96 void *libHandle; 97 GsInterfaceType *(*getDisplayColor)(const std::vector<displaycolor::DisplayInfo> &); 98 }; 99 100 #endif //DISPLAY_COLOR_LOADER_H 101