drm+crypto HAL default implementation
Test: compiles, links
bug:32815560
Change-Id: I49595734aca46c818bb3685934373a627a98a6ed
diff --git a/drm/crypto/1.0/default/Android.mk b/drm/crypto/1.0/default/Android.mk
new file mode 100644
index 0000000..83794ac
--- /dev/null
+++ b/drm/crypto/1.0/default/Android.mk
@@ -0,0 +1,41 @@
+# Copyright (C) 2016, 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_MODULE := android.hardware.drm.crypto@1.0-impl
+LOCAL_MODULE_RELATIVE_PATH := hw
+LOCAL_SRC_FILES := \
+ CryptoFactory.cpp \
+ CryptoPlugin.cpp \
+ TypeConvert.cpp \
+
+LOCAL_SHARED_LIBRARIES := \
+ libhidlbase \
+ libhidltransport \
+ libhwbinder \
+ libhidlmemory \
+ libutils \
+ liblog \
+ libmediadrm \
+ libstagefright_foundation \
+ android.hardware.drm.crypto@1.0 \
+ android.hidl.memory@1.0
+
+LOCAL_C_INCLUDES := \
+ frameworks/native/include \
+ frameworks/av/include
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/drm/crypto/1.0/default/CryptoFactory.cpp b/drm/crypto/1.0/default/CryptoFactory.cpp
new file mode 100644
index 0000000..e67a990
--- /dev/null
+++ b/drm/crypto/1.0/default/CryptoFactory.cpp
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+#include "CryptoFactory.h"
+#include "CryptoPlugin.h"
+#include "TypeConvert.h"
+#include <utils/Log.h>
+
+namespace android {
+namespace hardware {
+namespace drm {
+namespace crypto {
+namespace V1_0 {
+namespace implementation {
+
+ CryptoFactory::CryptoFactory() :
+ loader("/vendor/lib/mediadrm", "createCryptoFactory", "crypto") {}
+
+ // Methods from ::android::hardware::drm::crypto::V1_0::ICryptoFactory follow.
+ Return<bool> CryptoFactory::isCryptoSchemeSupported(
+ const hidl_array<uint8_t, 16>& uuid) {
+ for (size_t i = 0; i < loader.factoryCount(); i++) {
+ if (loader.getFactory(i)->isCryptoSchemeSupported(uuid.data())) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ Return<void> CryptoFactory::createPlugin(const hidl_array<uint8_t, 16>& uuid,
+ const hidl_vec<uint8_t>& initData, createPlugin_cb _hidl_cb) {
+
+ for (size_t i = 0; i < loader.factoryCount(); i++) {
+ if (loader.getFactory(i)->isCryptoSchemeSupported(uuid.data())) {
+ android::CryptoPlugin *legacyPlugin = NULL;
+ status_t status = loader.getFactory(i)->createPlugin(uuid.data(),
+ initData.data(), initData.size(), &legacyPlugin);
+ CryptoPlugin *newPlugin = NULL;
+ if (legacyPlugin == NULL) {
+ ALOGE("Crypto legacy HAL: failed to create crypto plugin");
+ } else {
+ newPlugin = new CryptoPlugin(legacyPlugin);
+ }
+ _hidl_cb(toStatus(status), newPlugin);
+ return Void();
+ }
+ }
+ _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, NULL);
+ return Void();
+ }
+
+ ICryptoFactory* HIDL_FETCH_ICryptoFactory(const char /* *name */) {
+ return new CryptoFactory();
+ }
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace crypto
+} // namespace drm
+} // namespace hardware
+} // namespace android
diff --git a/drm/crypto/1.0/default/CryptoFactory.h b/drm/crypto/1.0/default/CryptoFactory.h
new file mode 100644
index 0000000..0855996
--- /dev/null
+++ b/drm/crypto/1.0/default/CryptoFactory.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2016 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 ANDROID_HARDWARE_DRM_CRYPTO_V1_0__CRYPTOFACTORY_H
+#define ANDROID_HARDWARE_DRM_CRYPTO_V1_0__CRYPTOFACTORY_H
+
+#include <android/hardware/drm/crypto/1.0/ICryptoFactory.h>
+#include <hidl/Status.h>
+#include <media/hardware/CryptoAPI.h>
+#include <media/PluginLoader.h>
+#include <media/SharedLibrary.h>
+
+namespace android {
+namespace hardware {
+namespace drm {
+namespace crypto {
+namespace V1_0 {
+namespace implementation {
+
+using ::android::hardware::drm::crypto::V1_0::ICryptoFactory;
+using ::android::hardware::drm::crypto::V1_0::ICryptoPlugin;
+using ::android::hardware::hidl_array;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::sp;
+
+struct CryptoFactory : public ICryptoFactory {
+ CryptoFactory();
+ virtual ~CryptoFactory() {}
+
+ // Methods from ::android::hardware::drm::crypto::V1_0::ICryptoFactory follow.
+
+ Return<bool> isCryptoSchemeSupported(const hidl_array<uint8_t, 16>& uuid)
+ override;
+
+ Return<void> createPlugin(const hidl_array<uint8_t, 16>& uuid,
+ const hidl_vec<uint8_t>& initData, createPlugin_cb _hidl_cb)
+ override;
+
+private:
+ android::PluginLoader<android::CryptoFactory> loader;
+
+ CryptoFactory(const CryptoFactory &) = delete;
+ void operator=(const CryptoFactory &) = delete;
+};
+
+extern "C" ICryptoFactory* HIDL_FETCH_ICryptoFactory(const char* name);
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace crypto
+} // namespace drm
+} // namespace hardware
+} // namespace android
+
+#endif // ANDROID_HARDWARE_DRM_CRYPTO_V1_0__CRYPTOFACTORY_H
diff --git a/drm/crypto/1.0/default/CryptoPlugin.cpp b/drm/crypto/1.0/default/CryptoPlugin.cpp
new file mode 100644
index 0000000..9173d5b
--- /dev/null
+++ b/drm/crypto/1.0/default/CryptoPlugin.cpp
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+#include "CryptoPlugin.h"
+#include "TypeConvert.h"
+
+#include <media/stagefright/foundation/AString.h>
+
+#include <hidlmemory/mapping.h>
+#include <android/hidl/memory/1.0/IMemory.h>
+
+using android::hidl::memory::V1_0::IMemory;
+
+
+namespace android {
+namespace hardware {
+namespace drm {
+namespace crypto {
+namespace V1_0 {
+namespace implementation {
+
+ // Methods from ::android::hardware::drm::crypto::V1_0::ICryptoPlugin follow
+ Return<bool> CryptoPlugin::requiresSecureDecoderComponent(
+ const hidl_string& mime) {
+ return mLegacyPlugin->requiresSecureDecoderComponent(mime);
+ }
+
+ Return<void> CryptoPlugin::notifyResolution(uint32_t width,
+ uint32_t height) {
+ mLegacyPlugin->notifyResolution(width, height);
+ return Void();
+ }
+
+ Return<Status> CryptoPlugin::setMediaDrmSession(
+ const hidl_vec<uint8_t>& sessionId) {
+ return toStatus(mLegacyPlugin->setMediaDrmSession(toVector(sessionId)));
+ }
+
+ Return<void> CryptoPlugin::decrypt(bool secure,
+ const hidl_array<uint8_t, 16>& keyId,
+ const hidl_array<uint8_t, 16>& iv, Mode mode,
+ const Pattern& pattern, const hidl_vec<SubSample>& subSamples,
+ const hidl_memory &source, const DestinationBuffer& destination,
+ decrypt_cb _hidl_cb) {
+
+ android::CryptoPlugin::Mode legacyMode;
+ switch(mode) {
+ case Mode::UNENCRYPTED:
+ legacyMode = android::CryptoPlugin::kMode_Unencrypted;
+ break;
+ case Mode::AES_CTR:
+ legacyMode = android::CryptoPlugin::kMode_AES_CTR;
+ break;
+ case Mode::AES_CBC_CTS:
+ legacyMode = android::CryptoPlugin::kMode_AES_WV;
+ break;
+ case Mode::AES_CBC:
+ legacyMode = android::CryptoPlugin::kMode_AES_CBC;
+ break;
+ }
+ android::CryptoPlugin::Pattern legacyPattern;
+ legacyPattern.mEncryptBlocks = pattern.encryptBlocks;
+ legacyPattern.mSkipBlocks = pattern.skipBlocks;
+
+ android::CryptoPlugin::SubSample *legacySubSamples =
+ new android::CryptoPlugin::SubSample[subSamples.size()];
+
+ for (size_t i = 0; i < subSamples.size(); i++) {
+ legacySubSamples[i].mNumBytesOfClearData
+ = subSamples[i].numBytesOfClearData;
+ legacySubSamples[i].mNumBytesOfEncryptedData
+ = subSamples[i].numBytesOfEncryptedData;
+ }
+
+ AString detailMessage;
+
+ void *destPtr = NULL;
+ sp<IMemory> sharedMemory;
+
+ if (destination.type == BufferType::SHARED_MEMORY) {
+ sharedMemory = mapMemory(source);
+ destPtr = sharedMemory->getPointer();
+ sharedMemory->update();
+ } else if (destination.type == BufferType::NATIVE_HANDLE) {
+ native_handle_t *handle = const_cast<native_handle_t *>(
+ destination.secureMemory.getNativeHandle());
+ destPtr = static_cast<void *>(handle);
+ }
+ ssize_t result = mLegacyPlugin->decrypt(secure, keyId.data(), iv.data(),
+ legacyMode, legacyPattern, sharedMemory->getPointer(),
+ legacySubSamples, subSamples.size(), destPtr, &detailMessage);
+
+ if (destination.type == BufferType::SHARED_MEMORY) {
+ sharedMemory->commit();
+ }
+ delete[] legacySubSamples;
+
+ uint32_t status;
+ uint32_t bytesWritten;
+
+ if (result >= 0) {
+ status = android::OK;
+ bytesWritten = result;
+ } else {
+ status = -result;
+ bytesWritten = 0;
+ }
+
+ _hidl_cb(toStatus(status), bytesWritten, detailMessage.c_str());
+ return Void();
+ }
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace crypto
+} // namespace drm
+} // namespace hardware
+} // namespace android
diff --git a/drm/crypto/1.0/default/CryptoPlugin.h b/drm/crypto/1.0/default/CryptoPlugin.h
new file mode 100644
index 0000000..b17dade
--- /dev/null
+++ b/drm/crypto/1.0/default/CryptoPlugin.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2016 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 ANDROID_HARDWARE_DRM_CRYPTO_V1_0__CRYPTOPLUGIN_H
+#define ANDROID_HARDWARE_DRM_CRYPTO_V1_0__CRYPTOPLUGIN_H
+
+#include <media/hardware/CryptoAPI.h>
+#include <android/hardware/drm/crypto/1.0/ICryptoPlugin.h>
+#include <hidl/Status.h>
+
+namespace android {
+namespace hardware {
+namespace drm {
+namespace crypto {
+namespace V1_0 {
+namespace implementation {
+
+using ::android::hardware::drm::crypto::V1_0::DestinationBuffer;
+using ::android::hardware::drm::crypto::V1_0::ICryptoPlugin;
+using ::android::hardware::drm::crypto::V1_0::Mode;
+using ::android::hardware::drm::crypto::V1_0::Pattern;
+using ::android::hardware::drm::crypto::V1_0::SubSample;
+using ::android::hardware::hidl_array;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::sp;
+
+struct CryptoPlugin : public ICryptoPlugin {
+ CryptoPlugin(android::CryptoPlugin *plugin) : mLegacyPlugin(plugin) {}
+ ~CryptoPlugin() {delete mLegacyPlugin;}
+
+ // Methods from ::android::hardware::drm::crypto::V1_0::ICryptoPlugin
+ // follow.
+
+ Return<bool> requiresSecureDecoderComponent(const hidl_string& mime)
+ override;
+
+ Return<void> notifyResolution(uint32_t width, uint32_t height) override;
+
+ Return<Status> setMediaDrmSession(const hidl_vec<uint8_t>& sessionId)
+ override;
+
+ Return<void> decrypt(bool secure, const hidl_array<uint8_t, 16>& keyId,
+ const hidl_array<uint8_t, 16>& iv, Mode mode, const Pattern& pattern,
+ const hidl_vec<SubSample>& subSamples, const hidl_memory& source,
+ const DestinationBuffer& destination, decrypt_cb _hidl_cb) override;
+
+private:
+ android::CryptoPlugin *mLegacyPlugin;
+
+ CryptoPlugin() = delete;
+ CryptoPlugin(const CryptoPlugin &) = delete;
+ void operator=(const CryptoPlugin &) = delete;
+};
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace crypto
+} // namespace drm
+} // namespace hardware
+} // namespace android
+
+#endif // ANDROID_HARDWARE_DRM_CRYPTO_V1_0__CRYPTOPLUGIN_H
diff --git a/drm/crypto/1.0/default/TypeConvert.cpp b/drm/crypto/1.0/default/TypeConvert.cpp
new file mode 100644
index 0000000..d9cca6b
--- /dev/null
+++ b/drm/crypto/1.0/default/TypeConvert.cpp
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+#include "TypeConvert.h"
+
+namespace android {
+namespace hardware {
+namespace drm {
+namespace crypto {
+namespace V1_0 {
+namespace implementation {
+
+Status toStatus(status_t legacyStatus) {
+ Status status;
+ switch(legacyStatus) {
+ case android::ERROR_DRM_NO_LICENSE:
+ status = Status::ERROR_DRM_NO_LICENSE;
+ break;
+ case android::ERROR_DRM_LICENSE_EXPIRED:
+ status = Status::ERROR_DRM_LICENSE_EXPIRED;
+ break;
+ case android::ERROR_DRM_RESOURCE_BUSY:
+ status = Status::ERROR_DRM_RESOURCE_BUSY;
+ break;
+ case android::ERROR_DRM_INSUFFICIENT_OUTPUT_PROTECTION:
+ status = Status::ERROR_DRM_INSUFFICIENT_OUTPUT_PROTECTION;
+ break;
+ case android::ERROR_DRM_SESSION_NOT_OPENED:
+ status = Status::ERROR_DRM_SESSION_NOT_OPENED;
+ break;
+ case android::ERROR_DRM_CANNOT_HANDLE:
+ case android::BAD_VALUE:
+ status = Status::ERROR_DRM_CANNOT_HANDLE;
+ break;
+ default:
+ ALOGW("Unable to convert legacy status: %d, defaulting to UNKNOWN",
+ legacyStatus);
+ status = Status::ERROR_UNKNOWN_CRYPTO_EXCEPTION;
+ break;
+ }
+ return status;
+}
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace crypto
+} // namespace drm
+} // namespace hardware
+} // namespace android
diff --git a/drm/crypto/1.0/default/TypeConvert.h b/drm/crypto/1.0/default/TypeConvert.h
new file mode 100644
index 0000000..1655bab
--- /dev/null
+++ b/drm/crypto/1.0/default/TypeConvert.h
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2016 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 ANDROID_HARDWARE_DRM_CRYPTO_V1_0_TYPECONVERT
+#define ANDROID_HARDWARE_DRM_CRYPTO_V1_0_TYPECONVERT
+
+#include <utils/Vector.h>
+#include <media/stagefright/MediaErrors.h>
+#include <media/hardware/CryptoAPI.h>
+
+#include <hidl/MQDescriptor.h>
+#include <android/hardware/drm/crypto/1.0/types.h>
+
+namespace android {
+namespace hardware {
+namespace drm {
+namespace crypto {
+namespace V1_0 {
+namespace implementation {
+
+using ::android::hardware::hidl_vec;
+
+template<typename T> const hidl_vec<T> toHidlVec(const Vector<T> &Vector) {
+ hidl_vec<T> vec;
+ vec.setToExternal(const_cast<T *>(Vector.array()), Vector.size());
+ return vec;
+}
+
+template<typename T> hidl_vec<T> toHidlVec(Vector<T> &Vector) {
+ hidl_vec<T> vec;
+ vec.setToExternal(Vector.editArray(), Vector.size());
+ return vec;
+}
+
+template<typename T> const Vector<T> toVector(const hidl_vec<T> &vec) {
+ Vector<T> vector;
+ vector.appendArray(vec.data(), vec.size());
+ return *const_cast<const Vector<T> *>(&vector);
+}
+
+template<typename T> Vector<T> toVector(hidl_vec<T> &vec) {
+ Vector<T> vector;
+ vector.appendArray(vec.data(), vec.size());
+ return vector;
+}
+
+template<typename T, size_t SIZE> const Vector<T> toVector(
+ const hidl_array<T, SIZE> &array) {
+ Vector<T> vector;
+ vector.appendArray(array.data(), array.size());
+ return vector;
+}
+
+template<typename T, size_t SIZE> Vector<T> toVector(
+ hidl_array<T, SIZE> &array) {
+ Vector<T> vector;
+ vector.appendArray(array.data(), array.size());
+ return vector;
+}
+
+Status toStatus(status_t legacyStatus);
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace crypto
+} // namespace drm
+} // namespace hardware
+} // namespace android
+
+#endif // ANDROID_HARDWARE_DRM_CRYPTO_V1_0_TYPECONVERT