107770c78e18c5b09ba116fa1e779fe4408c42e3fJiyong Park/** 207770c78e18c5b09ba116fa1e779fe4408c42e3fJiyong Park * Copyright (C) 2016 The Android Open Source Project 307770c78e18c5b09ba116fa1e779fe4408c42e3fJiyong Park * 407770c78e18c5b09ba116fa1e779fe4408c42e3fJiyong Park * Licensed under the Apache License, Version 2.0 (the "License"); 507770c78e18c5b09ba116fa1e779fe4408c42e3fJiyong Park * you may not use this file except in compliance with the License. 607770c78e18c5b09ba116fa1e779fe4408c42e3fJiyong Park * You may obtain a copy of the License at 707770c78e18c5b09ba116fa1e779fe4408c42e3fJiyong Park * 807770c78e18c5b09ba116fa1e779fe4408c42e3fJiyong Park * http://www.apache.org/licenses/LICENSE-2.0 907770c78e18c5b09ba116fa1e779fe4408c42e3fJiyong Park * 1007770c78e18c5b09ba116fa1e779fe4408c42e3fJiyong Park * Unless required by applicable law or agreed to in writing, software 1107770c78e18c5b09ba116fa1e779fe4408c42e3fJiyong Park * distributed under the License is distributed on an "AS IS" BASIS, 1207770c78e18c5b09ba116fa1e779fe4408c42e3fJiyong Park * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1307770c78e18c5b09ba116fa1e779fe4408c42e3fJiyong Park * See the License for the specific language governing permissions and 1407770c78e18c5b09ba116fa1e779fe4408c42e3fJiyong Park * limitations under the License. 1507770c78e18c5b09ba116fa1e779fe4408c42e3fJiyong Park */ 1607770c78e18c5b09ba116fa1e779fe4408c42e3fJiyong Park 1707770c78e18c5b09ba116fa1e779fe4408c42e3fJiyong Park#ifndef PLUGIN_LOADER_H_ 1807770c78e18c5b09ba116fa1e779fe4408c42e3fJiyong Park#define PLUGIN_LOADER_H_ 1907770c78e18c5b09ba116fa1e779fe4408c42e3fJiyong Park 2007770c78e18c5b09ba116fa1e779fe4408c42e3fJiyong Park#include "SharedLibrary.h" 2107770c78e18c5b09ba116fa1e779fe4408c42e3fJiyong Park#include <utils/Log.h> 2207770c78e18c5b09ba116fa1e779fe4408c42e3fJiyong Park#include <utils/String8.h> 2307770c78e18c5b09ba116fa1e779fe4408c42e3fJiyong Park#include <utils/Vector.h> 2407770c78e18c5b09ba116fa1e779fe4408c42e3fJiyong Park 2507770c78e18c5b09ba116fa1e779fe4408c42e3fJiyong Parknamespace android { 2607770c78e18c5b09ba116fa1e779fe4408c42e3fJiyong Parknamespace hardware { 2707770c78e18c5b09ba116fa1e779fe4408c42e3fJiyong Parknamespace drm { 2807770c78e18c5b09ba116fa1e779fe4408c42e3fJiyong Parknamespace V1_0 { 2907770c78e18c5b09ba116fa1e779fe4408c42e3fJiyong Parknamespace helper { 3007770c78e18c5b09ba116fa1e779fe4408c42e3fJiyong Park 3107770c78e18c5b09ba116fa1e779fe4408c42e3fJiyong Parktemplate <class T> 3207770c78e18c5b09ba116fa1e779fe4408c42e3fJiyong Parkclass PluginLoader { 3307770c78e18c5b09ba116fa1e779fe4408c42e3fJiyong Park 3407770c78e18c5b09ba116fa1e779fe4408c42e3fJiyong Park public: 3507770c78e18c5b09ba116fa1e779fe4408c42e3fJiyong Park PluginLoader(const char *dir, const char *entry) { 3607770c78e18c5b09ba116fa1e779fe4408c42e3fJiyong Park /** 3707770c78e18c5b09ba116fa1e779fe4408c42e3fJiyong Park * scan all plugins in the plugin directory and add them to the 3807770c78e18c5b09ba116fa1e779fe4408c42e3fJiyong Park * factories list. 3907770c78e18c5b09ba116fa1e779fe4408c42e3fJiyong Park */ 4007770c78e18c5b09ba116fa1e779fe4408c42e3fJiyong Park String8 pluginDir(dir); 4107770c78e18c5b09ba116fa1e779fe4408c42e3fJiyong Park 4207770c78e18c5b09ba116fa1e779fe4408c42e3fJiyong Park DIR* pDir = opendir(pluginDir.string()); 4307770c78e18c5b09ba116fa1e779fe4408c42e3fJiyong Park if (pDir == NULL) { 4407770c78e18c5b09ba116fa1e779fe4408c42e3fJiyong Park ALOGE("Failed to find plugin directory %s", pluginDir.string()); 4507770c78e18c5b09ba116fa1e779fe4408c42e3fJiyong Park } else { 4607770c78e18c5b09ba116fa1e779fe4408c42e3fJiyong Park struct dirent* pEntry; 4707770c78e18c5b09ba116fa1e779fe4408c42e3fJiyong Park while ((pEntry = readdir(pDir))) { 4807770c78e18c5b09ba116fa1e779fe4408c42e3fJiyong Park String8 file(pEntry->d_name); 4907770c78e18c5b09ba116fa1e779fe4408c42e3fJiyong Park if (file.getPathExtension() == ".so") { 5007770c78e18c5b09ba116fa1e779fe4408c42e3fJiyong Park String8 path = pluginDir + "/" + pEntry->d_name; 5107770c78e18c5b09ba116fa1e779fe4408c42e3fJiyong Park T *plugin = loadOne(path, entry); 5207770c78e18c5b09ba116fa1e779fe4408c42e3fJiyong Park if (plugin) { 5307770c78e18c5b09ba116fa1e779fe4408c42e3fJiyong Park factories.push(plugin); 5407770c78e18c5b09ba116fa1e779fe4408c42e3fJiyong Park } 5507770c78e18c5b09ba116fa1e779fe4408c42e3fJiyong Park } 5607770c78e18c5b09ba116fa1e779fe4408c42e3fJiyong Park } 5707770c78e18c5b09ba116fa1e779fe4408c42e3fJiyong Park closedir(pDir); 5807770c78e18c5b09ba116fa1e779fe4408c42e3fJiyong Park } 5907770c78e18c5b09ba116fa1e779fe4408c42e3fJiyong Park } 6007770c78e18c5b09ba116fa1e779fe4408c42e3fJiyong Park 6107770c78e18c5b09ba116fa1e779fe4408c42e3fJiyong Park ~PluginLoader() { 6207770c78e18c5b09ba116fa1e779fe4408c42e3fJiyong Park for (size_t i = 0; i < factories.size(); i++) { 6307770c78e18c5b09ba116fa1e779fe4408c42e3fJiyong Park delete factories[i]; 6407770c78e18c5b09ba116fa1e779fe4408c42e3fJiyong Park } 6507770c78e18c5b09ba116fa1e779fe4408c42e3fJiyong Park } 6607770c78e18c5b09ba116fa1e779fe4408c42e3fJiyong Park 6707770c78e18c5b09ba116fa1e779fe4408c42e3fJiyong Park T *getFactory(size_t i) const { 6807770c78e18c5b09ba116fa1e779fe4408c42e3fJiyong Park return factories[i]; 6907770c78e18c5b09ba116fa1e779fe4408c42e3fJiyong Park } 7007770c78e18c5b09ba116fa1e779fe4408c42e3fJiyong Park 7107770c78e18c5b09ba116fa1e779fe4408c42e3fJiyong Park size_t factoryCount() const {return factories.size();} 7207770c78e18c5b09ba116fa1e779fe4408c42e3fJiyong Park 7307770c78e18c5b09ba116fa1e779fe4408c42e3fJiyong Park private: 7407770c78e18c5b09ba116fa1e779fe4408c42e3fJiyong Park T* loadOne(const char *path, const char *entry) { 7507770c78e18c5b09ba116fa1e779fe4408c42e3fJiyong Park sp<SharedLibrary> library = new SharedLibrary(String8(path)); 7607770c78e18c5b09ba116fa1e779fe4408c42e3fJiyong Park if (!library.get()) { 7707770c78e18c5b09ba116fa1e779fe4408c42e3fJiyong Park ALOGE("Failed to open plugin library %s: %s", path, 7807770c78e18c5b09ba116fa1e779fe4408c42e3fJiyong Park library->lastError()); 7907770c78e18c5b09ba116fa1e779fe4408c42e3fJiyong Park } else { 8007770c78e18c5b09ba116fa1e779fe4408c42e3fJiyong Park typedef T *(*CreateFactoryFunc)(); 8107770c78e18c5b09ba116fa1e779fe4408c42e3fJiyong Park CreateFactoryFunc createFactoryFunc = 8207770c78e18c5b09ba116fa1e779fe4408c42e3fJiyong Park (CreateFactoryFunc)library->lookup(entry); 8307770c78e18c5b09ba116fa1e779fe4408c42e3fJiyong Park if (createFactoryFunc) { 8407770c78e18c5b09ba116fa1e779fe4408c42e3fJiyong Park ALOGV("Found plugin factory entry %s in %s", entry, path); 8507770c78e18c5b09ba116fa1e779fe4408c42e3fJiyong Park libraries.push(library); 8607770c78e18c5b09ba116fa1e779fe4408c42e3fJiyong Park T* result = createFactoryFunc(); 8707770c78e18c5b09ba116fa1e779fe4408c42e3fJiyong Park return result; 8807770c78e18c5b09ba116fa1e779fe4408c42e3fJiyong Park } 8907770c78e18c5b09ba116fa1e779fe4408c42e3fJiyong Park } 9007770c78e18c5b09ba116fa1e779fe4408c42e3fJiyong Park return NULL; 9107770c78e18c5b09ba116fa1e779fe4408c42e3fJiyong Park } 9207770c78e18c5b09ba116fa1e779fe4408c42e3fJiyong Park 9307770c78e18c5b09ba116fa1e779fe4408c42e3fJiyong Park Vector<T *> factories; 9407770c78e18c5b09ba116fa1e779fe4408c42e3fJiyong Park Vector<sp<SharedLibrary> > libraries; 9507770c78e18c5b09ba116fa1e779fe4408c42e3fJiyong Park 9607770c78e18c5b09ba116fa1e779fe4408c42e3fJiyong Park PluginLoader(const PluginLoader &) = delete; 9707770c78e18c5b09ba116fa1e779fe4408c42e3fJiyong Park void operator=(const PluginLoader &) = delete; 9807770c78e18c5b09ba116fa1e779fe4408c42e3fJiyong Park}; 9907770c78e18c5b09ba116fa1e779fe4408c42e3fJiyong Park 10007770c78e18c5b09ba116fa1e779fe4408c42e3fJiyong Park} 10107770c78e18c5b09ba116fa1e779fe4408c42e3fJiyong Park} 10207770c78e18c5b09ba116fa1e779fe4408c42e3fJiyong Park} 10307770c78e18c5b09ba116fa1e779fe4408c42e3fJiyong Park} 10407770c78e18c5b09ba116fa1e779fe4408c42e3fJiyong Park} // namespace android 10507770c78e18c5b09ba116fa1e779fe4408c42e3fJiyong Park 10607770c78e18c5b09ba116fa1e779fe4408c42e3fJiyong Park#endif // PLUGIN_LOADER_H_ 10707770c78e18c5b09ba116fa1e779fe4408c42e3fJiyong Park 108