Reorganize drm hal modules

Previously the drm and crypto plugins were separate hals.
This implied a separation of implementation libraries which
causes problems for some drm schemes. The reorganization
combines the hals into a single interface under drm.

Tests: basic gtests passing

Change-Id: I5cde6ff9f60625a0219731c4dbfcaefbd9f27f88
related-to-bug: 32815560
diff --git a/drm/1.0/default/CryptoPlugin.cpp b/drm/1.0/default/CryptoPlugin.cpp
new file mode 100644
index 0000000..073f030
--- /dev/null
+++ b/drm/1.0/default/CryptoPlugin.cpp
@@ -0,0 +1,142 @@
+/*
+ * 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 <android/hidl/memory/1.0/IMemory.h>
+#include <hidlmemory/mapping.h>
+#include <media/stagefright/foundation/AString.h>
+#include <utils/Log.h>
+
+using android::hardware::hidl_memory;
+using android::hidl::memory::V1_0::IMemory;
+
+namespace android {
+namespace hardware {
+namespace drm {
+namespace V1_0 {
+namespace implementation {
+
+    // Methods from ::android::hardware::drm::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::setSharedBufferBase(const hidl_memory& base) {
+        mSharedBufferBase = mapMemory(base);
+        return Void();
+    }
+
+    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 SharedBuffer& source, uint64_t offset,
+            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;
+
+        if (source.offset + offset + source.size > mSharedBufferBase->getSize()) {
+            _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0, "invalid buffer size");
+            return Void();
+        }
+
+        uint8_t *base = static_cast<uint8_t *>
+                (static_cast<void *>(mSharedBufferBase->getPointer()));
+        void *srcPtr = static_cast<void *>(base + source.offset + offset);
+
+        void *destPtr = NULL;
+        if (destination.type == BufferType::SHARED_MEMORY) {
+            const SharedBuffer& destBuffer = destination.nonsecureMemory;
+            if (destBuffer.offset + destBuffer.size > mSharedBufferBase->getSize()) {
+                _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0, "invalid buffer size");
+                return Void();
+            }
+            destPtr = static_cast<void *>(base + destination.nonsecureMemory.offset);
+        } 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, srcPtr, legacySubSamples,
+                subSamples.size(), destPtr, &detailMessage);
+
+        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 drm
+}  // namespace hardware
+}  // namespace android