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 PLUGIN_LOADER_H_ 18 #define PLUGIN_LOADER_H_ 19 20 #include "SharedLibrary.h" 21 #include <utils/Log.h> 22 #include <utils/String8.h> 23 #include <utils/Vector.h> 24 25 namespace android { 26 27 template <class T> 28 class PluginLoader { 29 30 public: 31 PluginLoader(const char *dir, const char *entry) { 32 /** 33 * scan all plugins in the plugin directory and add them to the 34 * factories list. 35 */ 36 String8 pluginDir(dir); 37 38 DIR* pDir = opendir(pluginDir.string()); 39 if (pDir == NULL) { 40 ALOGE("Failed to find plugin directory %s", pluginDir.string()); 41 } else { 42 struct dirent* pEntry; 43 while ((pEntry = readdir(pDir))) { 44 String8 file(pEntry->d_name); 45 if (file.getPathExtension() == ".so") { 46 String8 path = pluginDir + "/" + pEntry->d_name; 47 T *plugin = loadOne(path, entry); 48 if (plugin) { 49 factories.push(plugin); 50 } 51 } 52 } 53 closedir(pDir); 54 } 55 } 56 57 ~PluginLoader() { 58 for (size_t i = 0; i < factories.size(); i++) { 59 delete factories[i]; 60 } 61 } 62 63 T *getFactory(size_t i) const { 64 return factories[i]; 65 } 66 67 size_t factoryCount() const {return factories.size();} 68 69 private: 70 T* loadOne(const char *path, const char *entry) { 71 sp<SharedLibrary> library = new SharedLibrary(String8(path)); 72 if (!library.get()) { 73 ALOGE("Failed to open plugin library %s: %s", path, 74 library->lastError()); 75 } else { 76 typedef T *(*CreateFactoryFunc)(); 77 CreateFactoryFunc createFactoryFunc = 78 (CreateFactoryFunc)library->lookup(entry); 79 if (createFactoryFunc) { 80 ALOGV("Found plugin factory entry %s in %s", entry, path); 81 libraries.push(library); 82 T* result = createFactoryFunc(); 83 return result; 84 } 85 } 86 return NULL; 87 } 88 89 Vector<T *> factories; 90 Vector<sp<SharedLibrary> > libraries; 91 92 PluginLoader(const PluginLoader &) = delete; 93 void operator=(const PluginLoader &) = delete; 94 }; 95 96 } // namespace android 97 98 #endif // PLUGIN_LOADER_H_ 99 100