Convert libdrmframework and drmserver to Android.bp

See build/soong/README.md for more information.

Also moves a few headers into the same library as their
implementation, and fixes a few includes to go through the
global frameworks/av/include path instead of manually adding
frameworks/av/include/drm.

Test: m -j checkbuild
Change-Id: I0c2d2f2262e7ed78d80a0d44795705c64b797ff0
diff --git a/drm/drmserver/Android.bp b/drm/drmserver/Android.bp
new file mode 100644
index 0000000..c25a0a1
--- /dev/null
+++ b/drm/drmserver/Android.bp
@@ -0,0 +1,46 @@
+//
+// 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.
+//
+
+cc_binary {
+    name: "drmserver",
+
+    srcs: [
+        "main_drmserver.cpp",
+        "DrmManager.cpp",
+        "DrmManagerService.cpp",
+    ],
+
+    shared_libs: [
+        "libmedia",
+        "libutils",
+        "liblog",
+        "libbinder",
+        "libdl",
+        "libselinux",
+    ],
+
+    static_libs: ["libdrmframeworkcommon"],
+
+    cflags: [
+        "-Wall",
+        "-Wextra",
+        "-Werror",
+    ],
+
+    compile_multilib: "32",
+
+    init_rc: ["drmserver.rc"],
+}
diff --git a/drm/drmserver/Android.mk b/drm/drmserver/Android.mk
deleted file mode 100644
index 3b8bb04..0000000
--- a/drm/drmserver/Android.mk
+++ /dev/null
@@ -1,49 +0,0 @@
-#
-# 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.
-#
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES:= \
-    main_drmserver.cpp \
-    DrmManager.cpp \
-    DrmManagerService.cpp
-
-LOCAL_SHARED_LIBRARIES := \
-    libmedia \
-    libutils \
-    liblog \
-    libbinder \
-    libdl \
-    libselinux
-
-LOCAL_STATIC_LIBRARIES := libdrmframeworkcommon
-
-LOCAL_C_INCLUDES := \
-    $(TOP)/frameworks/av/include \
-    $(TOP)/frameworks/av/drm/libdrmframework/include \
-    $(TOP)/frameworks/av/drm/libdrmframework/plugins/common/include
-
-LOCAL_CFLAGS += -Wall -Wextra -Werror
-
-LOCAL_MODULE:= drmserver
-
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_32_BIT_ONLY := true
-
-LOCAL_INIT_RC := drmserver.rc
-
-include $(BUILD_EXECUTABLE)
diff --git a/drm/drmserver/DrmManager.h b/drm/drmserver/DrmManager.h
new file mode 100644
index 0000000..e7cdd36
--- /dev/null
+++ b/drm/drmserver/DrmManager.h
@@ -0,0 +1,168 @@
+/*
+ * 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 __DRM_MANAGER_H__
+#define __DRM_MANAGER_H__
+
+#include <utils/Errors.h>
+#include <utils/threads.h>
+#include <drm/drm_framework_common.h>
+#include "IDrmEngine.h"
+#include "PlugInManager.h"
+#include "IDrmServiceListener.h"
+
+namespace android {
+
+class IDrmManager;
+class DrmRegistrationInfo;
+class DrmUnregistrationInfo;
+class DrmRightsAcquisitionInfo;
+class DrmConstraints;
+class DrmMetadata;
+class DrmRights;
+class DrmInfo;
+class DrmInfoStatus;
+class DrmConvertedStatus;
+class DrmInfoRequest;
+class DrmSupportInfo;
+class ActionDescription;
+
+/**
+ * This is implementation class for DRM Manager. This class delegates the
+ * functionality to corresponding DRM Engine.
+ *
+ * The DrmManagerService class creates an instance of this class.
+ *
+ */
+class DrmManager : public IDrmEngine::OnInfoListener {
+public:
+    DrmManager();
+    virtual ~DrmManager();
+
+public:
+    int addUniqueId(bool isNative);
+
+    void removeUniqueId(int uniqueId);
+
+    void addClient(int uniqueId);
+
+    void removeClient(int uniqueId);
+
+    status_t loadPlugIns();
+
+    status_t loadPlugIns(const String8& plugInDirPath);
+
+    status_t unloadPlugIns();
+
+    status_t setDrmServiceListener(
+            int uniqueId, const sp<IDrmServiceListener>& drmServiceListener);
+
+    DrmConstraints* getConstraints(int uniqueId, const String8* path, const int action);
+
+    DrmMetadata* getMetadata(int uniqueId, const String8* path);
+
+    bool canHandle(int uniqueId, const String8& path, const String8& mimeType);
+
+    DrmInfoStatus* processDrmInfo(int uniqueId, const DrmInfo* drmInfo);
+
+    DrmInfo* acquireDrmInfo(int uniqueId, const DrmInfoRequest* drmInfoRequest);
+
+    status_t saveRights(int uniqueId, const DrmRights& drmRights,
+            const String8& rightsPath, const String8& contentPath);
+
+    String8 getOriginalMimeType(int uniqueId, const String8& path, int fd);
+
+    int getDrmObjectType(int uniqueId, const String8& path, const String8& mimeType);
+
+    int checkRightsStatus(int uniqueId, const String8& path, int action);
+
+    status_t consumeRights(int uniqueId, DecryptHandle* decryptHandle, int action, bool reserve);
+
+    status_t setPlaybackStatus(
+            int uniqueId, DecryptHandle* decryptHandle, int playbackStatus, int64_t position);
+
+    bool validateAction(
+            int uniqueId, const String8& path, int action, const ActionDescription& description);
+
+    status_t removeRights(int uniqueId, const String8& path);
+
+    status_t removeAllRights(int uniqueId);
+
+    int openConvertSession(int uniqueId, const String8& mimeType);
+
+    DrmConvertedStatus* convertData(int uniqueId, int convertId, const DrmBuffer* inputData);
+
+    DrmConvertedStatus* closeConvertSession(int uniqueId, int convertId);
+
+    status_t getAllSupportInfo(int uniqueId, int* length, DrmSupportInfo** drmSupportInfoArray);
+
+    DecryptHandle* openDecryptSession(
+            int uniqueId, int fd, off64_t offset, off64_t length, const char* mime);
+
+    DecryptHandle* openDecryptSession(int uniqueId, const char* uri, const char* mime);
+
+    DecryptHandle* openDecryptSession(int uniqueId, const DrmBuffer& buf,
+            const String8& mimeType);
+
+    status_t closeDecryptSession(int uniqueId, DecryptHandle* decryptHandle);
+
+    status_t initializeDecryptUnit(int uniqueId, DecryptHandle* decryptHandle,
+            int decryptUnitId, const DrmBuffer* headerInfo);
+
+    status_t decrypt(int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId,
+            const DrmBuffer* encBuffer, DrmBuffer** decBuffer, DrmBuffer* IV);
+
+    status_t finalizeDecryptUnit(int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId);
+
+    ssize_t pread(int uniqueId, DecryptHandle* decryptHandle,
+            void* buffer, ssize_t numBytes, off64_t offset);
+
+    void onInfo(const DrmInfoEvent& event);
+
+private:
+    String8 getSupportedPlugInId(int uniqueId, const String8& path, const String8& mimeType);
+
+    String8 getSupportedPlugInId(const String8& mimeType);
+
+    String8 getSupportedPlugInIdFromPath(int uniqueId, const String8& path);
+
+    bool canHandle(int uniqueId, const String8& path);
+
+private:
+    enum {
+        kMaxNumUniqueIds = 0x1000,
+    };
+
+    bool mUniqueIdArray[kMaxNumUniqueIds];
+    static const String8 EMPTY_STRING;
+
+    int mDecryptSessionId;
+    int mConvertId;
+    Mutex mLock;
+    Mutex mListenerLock;
+    Mutex mDecryptLock;
+    Mutex mConvertLock;
+    TPlugInManager<IDrmEngine> mPlugInManager;
+    KeyedVector< DrmSupportInfo, String8 > mSupportInfoToPlugInIdMap;
+    KeyedVector< int, IDrmEngine*> mConvertSessionMap;
+    KeyedVector< int, sp<IDrmServiceListener> > mServiceListeners;
+    KeyedVector< int, IDrmEngine*> mDecryptSessionMap;
+};
+
+};
+
+#endif /* __DRM_MANAGER_H__ */
+
diff --git a/drm/drmserver/DrmManagerService.h b/drm/drmserver/DrmManagerService.h
new file mode 100644
index 0000000..45cee2e
--- /dev/null
+++ b/drm/drmserver/DrmManagerService.h
@@ -0,0 +1,149 @@
+/*
+ * 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 __DRM_MANAGER_SERVICE_H__
+#define __DRM_MANAGER_SERVICE_H__
+
+#include <utils/RefBase.h>
+#include <utils/KeyedVector.h>
+#include <binder/IInterface.h>
+#include <binder/Parcel.h>
+#include "IDrmManagerService.h"
+#include "IDrmServiceListener.h"
+
+namespace android {
+
+class DrmManager;
+class String8;
+class Mutex;
+
+/**
+ * This is the implementation class for DRM manager service. This delegates
+ * the responsibility to DrmManager.
+ *
+ * The instance of this class is created while starting the DRM manager service.
+ *
+ */
+class DrmManagerService : public BnDrmManagerService {
+public:
+    static void instantiate();
+
+private:
+    enum drm_perm_t {
+        CONSUME_RIGHTS          = 0,
+        SET_PLAYBACK_STATUS     = 1,
+        OPEN_DECRYPT_SESSION    = 2,
+        CLOSE_DECRYPT_SESSION   = 3,
+        INITIALIZE_DECRYPT_UNIT = 4,
+        DECRYPT                 = 5,
+        FINALIZE_DECRYPT_UNIT   = 6,
+        PREAD                   = 7,
+    };
+
+    static const char *const drm_perm_labels[];
+
+    DrmManagerService();
+    virtual ~DrmManagerService();
+
+    static const char *get_perm_label(drm_perm_t perm);
+
+    static bool selinuxIsProtectedCallAllowed(pid_t spid, drm_perm_t perm);
+
+    static bool isProtectedCallAllowed(drm_perm_t perm);
+
+public:
+    int addUniqueId(bool isNative);
+
+    void removeUniqueId(int uniqueId);
+
+    void addClient(int uniqueId);
+
+    void removeClient(int uniqueId);
+
+    status_t setDrmServiceListener(
+            int uniqueId, const sp<IDrmServiceListener>& drmServiceListener);
+
+    DrmConstraints* getConstraints(int uniqueId, const String8* path, const int action);
+
+    DrmMetadata* getMetadata(int uniqueId, const String8* path);
+
+    bool canHandle(int uniqueId, const String8& path, const String8& mimeType);
+
+    DrmInfoStatus* processDrmInfo(int uniqueId, const DrmInfo* drmInfo);
+
+    DrmInfo* acquireDrmInfo(int uniqueId, const DrmInfoRequest* drmInforequest);
+
+    status_t saveRights(int uniqueId, const DrmRights& drmRights,
+            const String8& rightsPath, const String8& contentPath);
+
+    String8 getOriginalMimeType(int uniqueId, const String8& path, int fd);
+
+    int getDrmObjectType(int uniqueId, const String8& path, const String8& mimeType);
+
+    int checkRightsStatus(int uniqueId, const String8& path,int action);
+
+    status_t consumeRights(int uniqueId, DecryptHandle* decryptHandle, int action, bool reserve);
+
+    status_t setPlaybackStatus(
+            int uniqueId, DecryptHandle* decryptHandle, int playbackStatus, int64_t position);
+
+    bool validateAction(int uniqueId, const String8& path,
+            int action, const ActionDescription& description);
+
+    status_t removeRights(int uniqueId, const String8& path);
+
+    status_t removeAllRights(int uniqueId);
+
+    int openConvertSession(int uniqueId, const String8& mimeType);
+
+    DrmConvertedStatus* convertData(int uniqueId, int convertId, const DrmBuffer* inputData);
+
+    DrmConvertedStatus* closeConvertSession(int uniqueId, int convertId);
+
+    status_t getAllSupportInfo(int uniqueId, int* length, DrmSupportInfo** drmSupportInfoArray);
+
+    DecryptHandle* openDecryptSession(
+        int uniqueId, int fd, off64_t offset, off64_t length, const char *mime);
+
+    DecryptHandle* openDecryptSession(
+        int uniqueId, const char* uri, const char* mime);
+
+    DecryptHandle* openDecryptSession(int uniqueId, const DrmBuffer& buf,
+            const String8& mimeType);
+
+    status_t closeDecryptSession(int uniqueId, DecryptHandle* decryptHandle);
+
+    status_t initializeDecryptUnit(int uniqueId, DecryptHandle* decryptHandle,
+            int decryptUnitId, const DrmBuffer* headerInfo);
+
+    status_t decrypt(int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId,
+            const DrmBuffer* encBuffer, DrmBuffer** decBuffer, DrmBuffer* IV);
+
+    status_t finalizeDecryptUnit(int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId);
+
+    ssize_t pread(int uniqueId, DecryptHandle* decryptHandle,
+            void* buffer, ssize_t numBytes, off64_t offset);
+
+    virtual status_t dump(int fd, const Vector<String16>& args);
+
+private:
+    DrmManager* mDrmManager;
+};
+
+};
+
+#endif /* __DRM_MANAGER_SERVICE_H__ */
+
diff --git a/drm/drmserver/PlugInManager.h b/drm/drmserver/PlugInManager.h
new file mode 100644
index 0000000..466844d
--- /dev/null
+++ b/drm/drmserver/PlugInManager.h
@@ -0,0 +1,261 @@
+/*
+ * 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 (size_t i = 0; i < plugInFileList.size(); ++i) {
+                loadPlugIn(plugInFileList[i]);
+            }
+        }
+    }
+
+    /**
+     * Unload all the plug-ins
+     *
+     */
+    void unloadPlugIns() {
+        for (size_t 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;
+
+        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);
+        }
+
+        return fileList;
+    }
+
+    /**
+     * True if the input name denotes plug-in
+     */
+    bool isPlugIn(const struct dirent* pEntry) const {
+        String8 sName(pEntry->d_name);
+        String8 extension(sName.getPathExtension());
+        // Note that the plug-in extension must exactly match case
+        return extension == String8(PLUGIN_EXTENSION);
+    }
+
+    /**
+     * 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__ */
+