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