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__ */
+