Initial contribution from Sony Corporation.

  Add DRM Framework to support DRM content playback
  together with StageFright.

  - DRM Framework code is added
     - include/drm
     - drm
  - api/current.xml is updated to include DRM Framework Java APIs
  - cmds/servicemanager/service_manager.c is modified
    to add drmManager and drmIOService.

Change-Id: I6d7bc9c7067362b500e530988a9ce241761866fb
diff --git a/drm/libdrmframework/include/PlugInManager.h b/drm/libdrmframework/include/PlugInManager.h
new file mode 100644
index 0000000..9ad195f
--- /dev/null
+++ b/drm/libdrmframework/include/PlugInManager.h
@@ -0,0 +1,273 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __PLUGIN_MANAGER_H__
+#define __PLUGIN_MANAGER_H__
+
+#include <dlfcn.h>
+#include <sys/types.h>
+#include <dirent.h>
+
+#include <utils/String8.h>
+#include <utils/Vector.h>
+#include <utils/KeyedVector.h>
+
+namespace android {
+
+const char* const PLUGIN_MANAGER_CREATE = "create";
+const char* const PLUGIN_MANAGER_DESTROY = "destroy";
+const char* const PLUGIN_EXTENSION = ".so";
+
+/**
+ * This is the template class for Plugin manager.
+ *
+ * The DrmManager uses this class to handle the plugins.
+ *
+ */
+template<typename Type>
+class TPlugInManager {
+private:
+    typedef void*      HANDLE;
+    typedef Type*      create_t(void);
+    typedef void       destroy_t(Type*);
+    typedef create_t*  FPCREATE;
+    typedef destroy_t* FPDESTORY;
+
+    typedef struct _PlugInContainer {
+        String8   sPath;
+        HANDLE    hHandle;
+        FPCREATE  fpCreate;
+        FPDESTORY fpDestory;
+        Type*     pInstance;
+
+        _PlugInContainer():
+            sPath("")
+            ,hHandle(NULL)
+            ,fpCreate(NULL)
+            ,fpDestory(NULL)
+            ,pInstance(NULL)
+            {}
+    } PlugInContainer;
+
+    typedef KeyedVector<String8, PlugInContainer*> PlugInMap;
+    PlugInMap m_plugInMap;
+
+    typedef Vector<String8> PlugInIdList;
+    PlugInIdList m_plugInIdList;
+
+public:
+    /**
+     * Load all the plug-ins in the specified directory
+     *
+     * @param[in] rsPlugInDirPath
+     *     Directory path which plug-ins (dynamic library) are stored
+     * @note Plug-ins should be implemented according to the specification
+     */
+    void loadPlugIns(const String8& rsPlugInDirPath) {
+        Vector<String8> plugInFileList = getPlugInPathList(rsPlugInDirPath);
+
+        if (!plugInFileList.isEmpty()) {
+            for (unsigned int i = 0; i < plugInFileList.size(); ++i) {
+                loadPlugIn(plugInFileList[i]);
+            }
+        }
+    }
+
+    /**
+     * Unload all the plug-ins
+     *
+     */
+    void unloadPlugIns() {
+        for (unsigned int i = 0; i < m_plugInIdList.size(); ++i) {
+            unloadPlugIn(m_plugInIdList[i]);
+        }
+        m_plugInIdList.clear();
+    }
+
+    /**
+     * Get all the IDs of available plug-ins
+     *
+     * @return[in] plugInIdList
+     *     String type Vector in which all plug-in IDs are stored
+     */
+    Vector<String8> getPlugInIdList() const {
+        return m_plugInIdList;
+    }
+
+    /**
+     * Get a plug-in reference of specified ID
+     *
+     * @param[in] rsPlugInId
+     *     Plug-in ID to be used
+     * @return plugIn
+     *     Reference of specified plug-in instance
+     */
+    Type& getPlugIn(const String8& rsPlugInId) {
+        if (!contains(rsPlugInId)) {
+            // This error case never happens
+        }
+        return *(m_plugInMap.valueFor(rsPlugInId)->pInstance);
+    }
+
+public:
+    /**
+     * Load a plug-in stored in the specified path
+     *
+     * @param[in] rsPlugInPath
+     *     Plug-in (dynamic library) file path
+     * @note Plug-in should be implemented according to the specification
+     */
+    void loadPlugIn(const String8& rsPlugInPath) {
+        if (contains(rsPlugInPath)) {
+            return;
+        }
+
+        PlugInContainer* pPlugInContainer = new PlugInContainer();
+
+        pPlugInContainer->hHandle = dlopen(rsPlugInPath.string(), RTLD_LAZY);
+
+        if (NULL == pPlugInContainer->hHandle) {
+            delete pPlugInContainer;
+            pPlugInContainer = NULL;
+            return;
+        }
+
+        pPlugInContainer->sPath = rsPlugInPath;
+        pPlugInContainer->fpCreate
+                = (FPCREATE)dlsym(pPlugInContainer->hHandle, PLUGIN_MANAGER_CREATE);
+        pPlugInContainer->fpDestory
+                = (FPDESTORY)dlsym(pPlugInContainer->hHandle, PLUGIN_MANAGER_DESTROY);
+
+        if (NULL != pPlugInContainer->fpCreate && NULL != pPlugInContainer->fpDestory) {
+            pPlugInContainer->pInstance = (Type*)pPlugInContainer->fpCreate();
+            m_plugInIdList.add(rsPlugInPath);
+            m_plugInMap.add(rsPlugInPath, pPlugInContainer);
+        } else {
+            dlclose(pPlugInContainer->hHandle);
+            delete pPlugInContainer;
+            pPlugInContainer = NULL;
+            return;
+        }
+    }
+
+    /**
+     * Unload a plug-in stored in the specified path
+     *
+     * @param[in] rsPlugInPath
+     *     Plug-in (dynamic library) file path
+     */
+    void unloadPlugIn(const String8& rsPlugInPath) {
+        if (!contains(rsPlugInPath)) {
+            return;
+        }
+
+        PlugInContainer* pPlugInContainer = m_plugInMap.valueFor(rsPlugInPath);
+        pPlugInContainer->fpDestory(pPlugInContainer->pInstance);
+        dlclose(pPlugInContainer->hHandle);
+
+        m_plugInMap.removeItem(rsPlugInPath);
+        delete pPlugInContainer;
+        pPlugInContainer = NULL;
+    }
+
+private:
+    /**
+     * True if TPlugInManager contains rsPlugInId
+     */
+    bool contains(const String8& rsPlugInId) {
+        return m_plugInMap.indexOfKey(rsPlugInId) != NAME_NOT_FOUND;
+    }
+
+    /**
+     * Return file path list of plug-ins stored in the specified directory
+     *
+     * @param[in] rsDirPath
+     *     Directory path in which plug-ins are stored
+     * @return plugInFileList
+     *     String type Vector in which file path of plug-ins are stored
+     */
+    Vector<String8> getPlugInPathList(const String8& rsDirPath) {
+        Vector<String8> fileList;
+        DIR* pDir = opendir(rsDirPath.string());
+        struct dirent* pEntry = new dirent();
+
+        while (NULL != pDir && NULL != (pEntry = readdir(pDir))) {
+            if (!isPlugIn(pEntry)) {
+                continue;
+            }
+            String8 plugInPath;
+            plugInPath += rsDirPath;
+            plugInPath += "/";
+            plugInPath += pEntry->d_name;
+
+            fileList.add(plugInPath);
+        }
+
+        if (NULL != pDir) {
+            closedir(pDir);
+        }
+        delete pEntry;
+        pEntry = NULL;
+
+        return fileList;
+    }
+
+    /**
+     * True if the input name denotes plug-in
+     */
+    bool isPlugIn(const struct dirent* pEntry) const {
+        String8 sName(pEntry->d_name);
+        int extentionPos = sName.size() - String8(PLUGIN_EXTENSION).size();
+        if (extentionPos < 0) {
+            return false;
+        }
+        return extentionPos == (int)sName.find(PLUGIN_EXTENSION);
+    }
+
+    /**
+     * True if the input entry is "." or ".."
+     */
+    bool isDotOrDDot(const struct dirent* pEntry) const {
+        String8 sName(pEntry->d_name);
+        return "." == sName || ".." == sName;
+    }
+
+    /**
+     * True if input entry is directory
+     */
+    bool isDirectory(const struct dirent* pEntry) const {
+        return DT_DIR == pEntry->d_type;
+    }
+
+    /**
+     * True if input entry is regular file
+     */
+    bool isRegularFile(const struct dirent* pEntry) const {
+        return DT_REG == pEntry->d_type;
+    }
+
+    /**
+     * True if input entry is link
+     */
+    bool isLink(const struct dirent* pEntry) const {
+        return DT_LNK == pEntry->d_type;
+    }
+};
+
+};
+
+#endif /* __PLUGIN_MANAGER_H__ */
+