19dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang/* 29dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang * Copyright (C) 2017 The Android Open Source Project 39dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang * 49dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang * Licensed under the Apache License, Version 2.0 (the "License"); 59dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang * you may not use this file except in compliance with the License. 69dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang * You may obtain a copy of the License at 79dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang * 89dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang * http://www.apache.org/licenses/LICENSE-2.0 99dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang * 109dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang * Unless required by applicable law or agreed to in writing, software 119dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang * distributed under the License is distributed on an "AS IS" BASIS, 129dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang * See the License for the specific language governing permissions and 149dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang * limitations under the License. 159dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang */ 169dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang 179dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang#ifndef MEDIA_CAS_LOADER_H_ 189dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang#define MEDIA_CAS_LOADER_H_ 199dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang 209dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang#include <dirent.h> 219dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang#include <dlfcn.h> 229dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang#include <media/SharedLibrary.h> 239dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang#include <utils/KeyedVector.h> 249dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang#include <utils/Mutex.h> 259dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang 269dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhangnamespace android { 279dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhangusing namespace std; 289dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhangusing namespace media; 299dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhangusing namespace MediaCas; 309dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang 319dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhangtemplate <class T> 329dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhangclass FactoryLoader { 339dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhangpublic: 349dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang FactoryLoader(const char *name) : 359dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang mFactory(NULL), mCreateFactoryFuncName(name) {} 369dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang 379dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang virtual ~FactoryLoader() { closeFactory(); } 389dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang 399dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang bool findFactoryForScheme( 409dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang int32_t CA_system_id, 419dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang sp<SharedLibrary> *library = NULL, 429dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang T** factory = NULL); 439dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang 449dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang bool enumeratePlugins(vector<ParcelableCasPluginDescriptor>* results); 459dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang 469dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhangprivate: 479dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang typedef T*(*CreateFactoryFunc)(); 489dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang 499dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang Mutex mMapLock; 509dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang T* mFactory; 519dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang const char *mCreateFactoryFuncName; 529dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang sp<SharedLibrary> mLibrary; 539dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang KeyedVector<int32_t, String8> mCASystemIdToLibraryPathMap; 549dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang KeyedVector<String8, wp<SharedLibrary> > mLibraryPathToOpenLibraryMap; 559dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang 569dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang bool loadFactoryForSchemeFromPath( 579dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang const String8 &path, 589dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang int32_t CA_system_id, 599dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang sp<SharedLibrary> *library, 609dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang T** factory); 619dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang 629dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang bool queryPluginsFromPath( 639dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang const String8 &path, 649dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang vector<ParcelableCasPluginDescriptor>* results); 659dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang 669dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang bool openFactory(const String8 &path); 679dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang void closeFactory(); 689dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang}; 699dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang 709dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhangtemplate <class T> 719dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhangbool FactoryLoader<T>::findFactoryForScheme( 729dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang int32_t CA_system_id, sp<SharedLibrary> *library, T** factory) { 739dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang if (library != NULL) { 749dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang library->clear(); 759dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang } 769dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang if (factory != NULL) { 779dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang *factory = NULL; 789dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang } 799dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang 809dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang Mutex::Autolock autoLock(mMapLock); 819dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang 829dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang // first check cache 839dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang ssize_t index = mCASystemIdToLibraryPathMap.indexOfKey(CA_system_id); 849dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang if (index >= 0) { 859dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang return loadFactoryForSchemeFromPath( 869dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang mCASystemIdToLibraryPathMap[index], 879dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang CA_system_id, library, factory); 889dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang } 899dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang 909dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang // no luck, have to search 913b1d140980a8329dd47f73e9fd8688ffcc13b216Chong Zhang String8 dirPath("/system/lib/mediacas"); 929dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang DIR* pDir = opendir(dirPath.string()); 939dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang 949dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang if (pDir == NULL) { 959dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang ALOGE("Failed to open plugin directory %s", dirPath.string()); 969dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang return false; 979dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang } 989dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang 999dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang struct dirent* pEntry; 1009dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang while ((pEntry = readdir(pDir))) { 1019dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang String8 pluginPath = dirPath + "/" + pEntry->d_name; 1029dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang if (pluginPath.getPathExtension() == ".so") { 1039dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang if (loadFactoryForSchemeFromPath( 1049dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang pluginPath, CA_system_id, library, factory)) { 1059dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang mCASystemIdToLibraryPathMap.add(CA_system_id, pluginPath); 1069dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang closedir(pDir); 1079dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang 1089dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang return true; 1099dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang } 1109dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang } 1119dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang } 1129dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang 1139dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang closedir(pDir); 1149dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang 1159dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang ALOGE("Failed to find plugin"); 1169dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang return false; 1179dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang} 1189dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang 1199dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhangtemplate <class T> 1209dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhangbool FactoryLoader<T>::enumeratePlugins( 1219dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang vector<ParcelableCasPluginDescriptor>* results) { 1229dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang ALOGI("enumeratePlugins"); 1239dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang 1249dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang results->clear(); 1259dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang 1263b1d140980a8329dd47f73e9fd8688ffcc13b216Chong Zhang String8 dirPath("/system/lib/mediacas"); 1279dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang DIR* pDir = opendir(dirPath.string()); 1289dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang 1299dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang if (pDir == NULL) { 1309dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang ALOGE("Failed to open plugin directory %s", dirPath.string()); 1319dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang return false; 1329dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang } 1339dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang 1349dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang Mutex::Autolock autoLock(mMapLock); 1359dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang 1369dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang struct dirent* pEntry; 1379dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang while ((pEntry = readdir(pDir))) { 1389dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang String8 pluginPath = dirPath + "/" + pEntry->d_name; 1399dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang if (pluginPath.getPathExtension() == ".so") { 1409dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang queryPluginsFromPath(pluginPath, results); 1419dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang } 1429dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang } 1439dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang return true; 1449dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang} 1459dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang 1469dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhangtemplate <class T> 1479dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhangbool FactoryLoader<T>::loadFactoryForSchemeFromPath( 1489dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang const String8 &path, int32_t CA_system_id, 1499dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang sp<SharedLibrary> *library, T** factory) { 1509dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang closeFactory(); 1519dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang 1529dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang if (!openFactory(path) || !mFactory->isSystemIdSupported(CA_system_id)) { 1539dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang closeFactory(); 1549dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang return false; 1559dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang } 1569dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang 1579dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang if (library != NULL) { 1589dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang *library = mLibrary; 1599dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang } 1609dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang if (factory != NULL) { 1619dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang *factory = mFactory; 1629dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang } 1639dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang return true; 1649dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang} 1659dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang 1669dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhangtemplate <class T> 1679dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhangbool FactoryLoader<T>::queryPluginsFromPath( 1689dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang const String8 &path, vector<ParcelableCasPluginDescriptor>* results) { 1699dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang closeFactory(); 1709dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang 1719dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang vector<CasPluginDescriptor> descriptors; 1729dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang if (!openFactory(path) || mFactory->queryPlugins(&descriptors) != OK) { 1739dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang closeFactory(); 1749dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang return false; 1759dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang } 1769dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang 1779dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang for (auto it = descriptors.begin(); it != descriptors.end(); it++) { 1789dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang results->push_back(ParcelableCasPluginDescriptor( 1799dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang it->CA_system_id, it->name)); 1809dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang } 1819dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang return true; 1829dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang} 1839dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang 1849dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhangtemplate <class T> 1859dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhangbool FactoryLoader<T>::openFactory(const String8 &path) { 1869dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang // get strong pointer to open shared library 1879dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang ssize_t index = mLibraryPathToOpenLibraryMap.indexOfKey(path); 1889dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang if (index >= 0) { 1899dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang mLibrary = mLibraryPathToOpenLibraryMap[index].promote(); 1909dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang } else { 1919dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang index = mLibraryPathToOpenLibraryMap.add(path, NULL); 1929dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang } 1939dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang 1949dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang if (!mLibrary.get()) { 1959dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang mLibrary = new SharedLibrary(path); 1969dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang if (!*mLibrary) { 1979dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang return false; 1989dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang } 1999dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang 2009dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang mLibraryPathToOpenLibraryMap.replaceValueAt(index, mLibrary); 2019dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang } 2029dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang 2039dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang CreateFactoryFunc createFactory = 2049dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang (CreateFactoryFunc)mLibrary->lookup(mCreateFactoryFuncName); 2059dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang if (createFactory == NULL || (mFactory = createFactory()) == NULL) { 2069dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang return false; 2079dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang } 2089dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang return true; 2099dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang} 2109dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang 2119dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhangtemplate <class T> 2129dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhangvoid FactoryLoader<T>::closeFactory() { 2139dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang delete mFactory; 2149dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang mFactory = NULL; 2159dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang mLibrary.clear(); 2169dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang} 2179dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang 2189dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang} // namespace android 2199dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang 2209dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang#endif // MEDIA_CAS_LOADER_H_ 221