Merge "rename some files related to MediaPlayer2."
diff --git a/drm/mediadrm/plugins/clearkey/common/Android.bp b/drm/mediadrm/plugins/clearkey/common/Android.bp
new file mode 100644
index 0000000..2c674e1
--- /dev/null
+++ b/drm/mediadrm/plugins/clearkey/common/Android.bp
@@ -0,0 +1,38 @@
+//
+// Copyright (C) 2018 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_library_static {
+ name: "libclearkeycommon",
+ vendor: true,
+
+ srcs: [
+ "ClearKeyUUID.cpp",
+ "Utils.cpp",
+ ],
+
+ cflags: ["-Wall", "-Werror"],
+
+ include_dirs: ["frameworks/av/include"],
+
+ shared_libs: ["libutils"],
+
+ export_include_dirs: ["include"],
+
+ sanitize: {
+ integer_overflow: true,
+ },
+}
+
diff --git a/drm/mediadrm/plugins/clearkey/ClearKeyUUID.cpp b/drm/mediadrm/plugins/clearkey/common/ClearKeyUUID.cpp
similarity index 100%
rename from drm/mediadrm/plugins/clearkey/ClearKeyUUID.cpp
rename to drm/mediadrm/plugins/clearkey/common/ClearKeyUUID.cpp
diff --git a/drm/mediadrm/plugins/clearkey/Utils.cpp b/drm/mediadrm/plugins/clearkey/common/Utils.cpp
similarity index 100%
rename from drm/mediadrm/plugins/clearkey/Utils.cpp
rename to drm/mediadrm/plugins/clearkey/common/Utils.cpp
diff --git a/drm/mediadrm/plugins/clearkey/ClearKeyUUID.h b/drm/mediadrm/plugins/clearkey/common/include/ClearKeyUUID.h
similarity index 100%
rename from drm/mediadrm/plugins/clearkey/ClearKeyUUID.h
rename to drm/mediadrm/plugins/clearkey/common/include/ClearKeyUUID.h
diff --git a/drm/mediadrm/plugins/clearkey/MimeType.h b/drm/mediadrm/plugins/clearkey/common/include/MimeType.h
similarity index 100%
rename from drm/mediadrm/plugins/clearkey/MimeType.h
rename to drm/mediadrm/plugins/clearkey/common/include/MimeType.h
diff --git a/drm/mediadrm/plugins/clearkey/Utils.h b/drm/mediadrm/plugins/clearkey/common/include/Utils.h
similarity index 100%
rename from drm/mediadrm/plugins/clearkey/Utils.h
rename to drm/mediadrm/plugins/clearkey/common/include/Utils.h
diff --git a/drm/mediadrm/plugins/clearkey/AesCtrDecryptor.cpp b/drm/mediadrm/plugins/clearkey/default/AesCtrDecryptor.cpp
similarity index 100%
rename from drm/mediadrm/plugins/clearkey/AesCtrDecryptor.cpp
rename to drm/mediadrm/plugins/clearkey/default/AesCtrDecryptor.cpp
diff --git a/drm/mediadrm/plugins/clearkey/Android.bp b/drm/mediadrm/plugins/clearkey/default/Android.bp
similarity index 90%
rename from drm/mediadrm/plugins/clearkey/Android.bp
rename to drm/mediadrm/plugins/clearkey/default/Android.bp
index 4b7a63c..7ba5708 100644
--- a/drm/mediadrm/plugins/clearkey/Android.bp
+++ b/drm/mediadrm/plugins/clearkey/default/Android.bp
@@ -16,10 +16,10 @@
cc_library_shared {
name: "libdrmclearkeyplugin",
+ vendor: true,
srcs: [
"AesCtrDecryptor.cpp",
- "ClearKeyUUID.cpp",
"CreatePluginFactories.cpp",
"CryptoFactory.cpp",
"CryptoPlugin.cpp",
@@ -29,10 +29,8 @@
"JsonWebKey.cpp",
"Session.cpp",
"SessionLibrary.cpp",
- "Utils.cpp",
],
- vendor: true,
relative_install_path: "mediadrm",
cflags: ["-Wall", "-Werror"],
@@ -44,16 +42,20 @@
"libutils",
],
- static_libs: ["libjsmn"],
+ static_libs: [
+ "libclearkeycommon",
+ "libjsmn"
+ ],
+
+ local_include_dirs: ["include"],
+ export_include_dirs: ["include"],
+ export_static_lib_headers: ["libjsmn"],
include_dirs: [
"frameworks/native/include",
"frameworks/av/include",
],
- export_include_dirs: ["."],
- export_static_lib_headers: ["libjsmn"],
-
sanitize: {
integer_overflow: true,
},
diff --git a/drm/mediadrm/plugins/clearkey/CreatePluginFactories.cpp b/drm/mediadrm/plugins/clearkey/default/CreatePluginFactories.cpp
similarity index 100%
rename from drm/mediadrm/plugins/clearkey/CreatePluginFactories.cpp
rename to drm/mediadrm/plugins/clearkey/default/CreatePluginFactories.cpp
diff --git a/drm/mediadrm/plugins/clearkey/CryptoFactory.cpp b/drm/mediadrm/plugins/clearkey/default/CryptoFactory.cpp
similarity index 97%
rename from drm/mediadrm/plugins/clearkey/CryptoFactory.cpp
rename to drm/mediadrm/plugins/clearkey/default/CryptoFactory.cpp
index eeb64c3..f15f92b 100644
--- a/drm/mediadrm/plugins/clearkey/CryptoFactory.cpp
+++ b/drm/mediadrm/plugins/clearkey/default/CryptoFactory.cpp
@@ -15,7 +15,7 @@
*/
//#define LOG_NDEBUG 0
-#define LOG_TAG "ClearKeyCryptoPlugin"
+#define LOG_TAG "ClearKeyCryptoFactory"
#include <utils/Log.h>
#include <utils/Errors.h>
diff --git a/drm/mediadrm/plugins/clearkey/CryptoPlugin.cpp b/drm/mediadrm/plugins/clearkey/default/CryptoPlugin.cpp
similarity index 100%
rename from drm/mediadrm/plugins/clearkey/CryptoPlugin.cpp
rename to drm/mediadrm/plugins/clearkey/default/CryptoPlugin.cpp
diff --git a/drm/mediadrm/plugins/clearkey/DrmFactory.cpp b/drm/mediadrm/plugins/clearkey/default/DrmFactory.cpp
similarity index 97%
rename from drm/mediadrm/plugins/clearkey/DrmFactory.cpp
rename to drm/mediadrm/plugins/clearkey/default/DrmFactory.cpp
index c83321b..8301e40 100644
--- a/drm/mediadrm/plugins/clearkey/DrmFactory.cpp
+++ b/drm/mediadrm/plugins/clearkey/default/DrmFactory.cpp
@@ -15,7 +15,7 @@
*/
//#define LOG_NDEBUG 0
-#define LOG_TAG "ClearKeyCryptoPlugin"
+#define LOG_TAG "ClearKeyDrmFactory"
#include <utils/Log.h>
#include <utils/Errors.h>
diff --git a/drm/mediadrm/plugins/clearkey/DrmPlugin.cpp b/drm/mediadrm/plugins/clearkey/default/DrmPlugin.cpp
similarity index 99%
rename from drm/mediadrm/plugins/clearkey/DrmPlugin.cpp
rename to drm/mediadrm/plugins/clearkey/default/DrmPlugin.cpp
index 944002d..1b8b8c1 100644
--- a/drm/mediadrm/plugins/clearkey/DrmPlugin.cpp
+++ b/drm/mediadrm/plugins/clearkey/default/DrmPlugin.cpp
@@ -15,7 +15,7 @@
*/
//#define LOG_NDEBUG 0
-#define LOG_TAG "ClearKeyCryptoPlugin"
+#define LOG_TAG "ClearKeyDrmPlugin"
#include <utils/Log.h>
#include <media/stagefright/MediaErrors.h>
diff --git a/drm/mediadrm/plugins/clearkey/InitDataParser.cpp b/drm/mediadrm/plugins/clearkey/default/InitDataParser.cpp
similarity index 100%
rename from drm/mediadrm/plugins/clearkey/InitDataParser.cpp
rename to drm/mediadrm/plugins/clearkey/default/InitDataParser.cpp
diff --git a/drm/mediadrm/plugins/clearkey/JsonWebKey.cpp b/drm/mediadrm/plugins/clearkey/default/JsonWebKey.cpp
similarity index 100%
rename from drm/mediadrm/plugins/clearkey/JsonWebKey.cpp
rename to drm/mediadrm/plugins/clearkey/default/JsonWebKey.cpp
diff --git a/drm/mediadrm/plugins/clearkey/Session.cpp b/drm/mediadrm/plugins/clearkey/default/Session.cpp
similarity index 98%
rename from drm/mediadrm/plugins/clearkey/Session.cpp
rename to drm/mediadrm/plugins/clearkey/default/Session.cpp
index d210f5e..b3ceaec 100644
--- a/drm/mediadrm/plugins/clearkey/Session.cpp
+++ b/drm/mediadrm/plugins/clearkey/default/Session.cpp
@@ -15,7 +15,7 @@
*/
//#define LOG_NDEBUG 0
-#define LOG_TAG "ClearKeyCryptoPlugin"
+#define LOG_TAG "ClearKeySession"
#include <utils/Log.h>
#include <media/stagefright/MediaErrors.h>
diff --git a/drm/mediadrm/plugins/clearkey/SessionLibrary.cpp b/drm/mediadrm/plugins/clearkey/default/SessionLibrary.cpp
similarity index 97%
rename from drm/mediadrm/plugins/clearkey/SessionLibrary.cpp
rename to drm/mediadrm/plugins/clearkey/default/SessionLibrary.cpp
index 0419f97..529230e 100644
--- a/drm/mediadrm/plugins/clearkey/SessionLibrary.cpp
+++ b/drm/mediadrm/plugins/clearkey/default/SessionLibrary.cpp
@@ -15,7 +15,7 @@
*/
//#define LOG_NDEBUG 0
-#define LOG_TAG "ClearKeyCryptoPlugin"
+#define LOG_TAG "ClearKeySessionLibrary"
#include <utils/Log.h>
#include <utils/String8.h>
diff --git a/drm/mediadrm/plugins/clearkey/AesCtrDecryptor.h b/drm/mediadrm/plugins/clearkey/default/include/AesCtrDecryptor.h
similarity index 100%
rename from drm/mediadrm/plugins/clearkey/AesCtrDecryptor.h
rename to drm/mediadrm/plugins/clearkey/default/include/AesCtrDecryptor.h
diff --git a/drm/mediadrm/plugins/clearkey/ClearKeyDrmProperties.h b/drm/mediadrm/plugins/clearkey/default/include/ClearKeyDrmProperties.h
similarity index 100%
rename from drm/mediadrm/plugins/clearkey/ClearKeyDrmProperties.h
rename to drm/mediadrm/plugins/clearkey/default/include/ClearKeyDrmProperties.h
diff --git a/drm/mediadrm/plugins/clearkey/ClearKeyTypes.h b/drm/mediadrm/plugins/clearkey/default/include/ClearKeyTypes.h
similarity index 100%
rename from drm/mediadrm/plugins/clearkey/ClearKeyTypes.h
rename to drm/mediadrm/plugins/clearkey/default/include/ClearKeyTypes.h
diff --git a/drm/mediadrm/plugins/clearkey/CreatePluginFactories.h b/drm/mediadrm/plugins/clearkey/default/include/CreatePluginFactories.h
similarity index 100%
rename from drm/mediadrm/plugins/clearkey/CreatePluginFactories.h
rename to drm/mediadrm/plugins/clearkey/default/include/CreatePluginFactories.h
diff --git a/drm/mediadrm/plugins/clearkey/CryptoFactory.h b/drm/mediadrm/plugins/clearkey/default/include/CryptoFactory.h
similarity index 100%
rename from drm/mediadrm/plugins/clearkey/CryptoFactory.h
rename to drm/mediadrm/plugins/clearkey/default/include/CryptoFactory.h
diff --git a/drm/mediadrm/plugins/clearkey/CryptoPlugin.h b/drm/mediadrm/plugins/clearkey/default/include/CryptoPlugin.h
similarity index 100%
rename from drm/mediadrm/plugins/clearkey/CryptoPlugin.h
rename to drm/mediadrm/plugins/clearkey/default/include/CryptoPlugin.h
diff --git a/drm/mediadrm/plugins/clearkey/DrmFactory.h b/drm/mediadrm/plugins/clearkey/default/include/DrmFactory.h
similarity index 100%
rename from drm/mediadrm/plugins/clearkey/DrmFactory.h
rename to drm/mediadrm/plugins/clearkey/default/include/DrmFactory.h
diff --git a/drm/mediadrm/plugins/clearkey/DrmPlugin.h b/drm/mediadrm/plugins/clearkey/default/include/DrmPlugin.h
similarity index 100%
rename from drm/mediadrm/plugins/clearkey/DrmPlugin.h
rename to drm/mediadrm/plugins/clearkey/default/include/DrmPlugin.h
diff --git a/drm/mediadrm/plugins/clearkey/InitDataParser.h b/drm/mediadrm/plugins/clearkey/default/include/InitDataParser.h
similarity index 100%
rename from drm/mediadrm/plugins/clearkey/InitDataParser.h
rename to drm/mediadrm/plugins/clearkey/default/include/InitDataParser.h
diff --git a/drm/mediadrm/plugins/clearkey/JsonWebKey.h b/drm/mediadrm/plugins/clearkey/default/include/JsonWebKey.h
similarity index 100%
rename from drm/mediadrm/plugins/clearkey/JsonWebKey.h
rename to drm/mediadrm/plugins/clearkey/default/include/JsonWebKey.h
diff --git a/drm/mediadrm/plugins/clearkey/Session.h b/drm/mediadrm/plugins/clearkey/default/include/Session.h
similarity index 100%
rename from drm/mediadrm/plugins/clearkey/Session.h
rename to drm/mediadrm/plugins/clearkey/default/include/Session.h
diff --git a/drm/mediadrm/plugins/clearkey/SessionLibrary.h b/drm/mediadrm/plugins/clearkey/default/include/SessionLibrary.h
similarity index 100%
rename from drm/mediadrm/plugins/clearkey/SessionLibrary.h
rename to drm/mediadrm/plugins/clearkey/default/include/SessionLibrary.h
diff --git a/drm/mediadrm/plugins/clearkey/tests/AesCtrDecryptorUnittest.cpp b/drm/mediadrm/plugins/clearkey/default/tests/AesCtrDecryptorUnittest.cpp
similarity index 100%
rename from drm/mediadrm/plugins/clearkey/tests/AesCtrDecryptorUnittest.cpp
rename to drm/mediadrm/plugins/clearkey/default/tests/AesCtrDecryptorUnittest.cpp
diff --git a/drm/mediadrm/plugins/clearkey/tests/Android.bp b/drm/mediadrm/plugins/clearkey/default/tests/Android.bp
similarity index 96%
rename from drm/mediadrm/plugins/clearkey/tests/Android.bp
rename to drm/mediadrm/plugins/clearkey/default/tests/Android.bp
index ea17bbb..4419865 100644
--- a/drm/mediadrm/plugins/clearkey/tests/Android.bp
+++ b/drm/mediadrm/plugins/clearkey/default/tests/Android.bp
@@ -29,6 +29,8 @@
"JsonWebKeyUnittest.cpp",
],
+ static_libs: ["libclearkeycommon"],
+
shared_libs: [
"libcrypto",
"libdrmclearkeyplugin",
diff --git a/drm/mediadrm/plugins/clearkey/tests/InitDataParserUnittest.cpp b/drm/mediadrm/plugins/clearkey/default/tests/InitDataParserUnittest.cpp
similarity index 100%
rename from drm/mediadrm/plugins/clearkey/tests/InitDataParserUnittest.cpp
rename to drm/mediadrm/plugins/clearkey/default/tests/InitDataParserUnittest.cpp
diff --git a/drm/mediadrm/plugins/clearkey/tests/JsonWebKeyUnittest.cpp b/drm/mediadrm/plugins/clearkey/default/tests/JsonWebKeyUnittest.cpp
similarity index 100%
rename from drm/mediadrm/plugins/clearkey/tests/JsonWebKeyUnittest.cpp
rename to drm/mediadrm/plugins/clearkey/default/tests/JsonWebKeyUnittest.cpp
diff --git a/drm/mediadrm/plugins/clearkey/hidl/AesCtrDecryptor.cpp b/drm/mediadrm/plugins/clearkey/hidl/AesCtrDecryptor.cpp
new file mode 100644
index 0000000..2fce0790
--- /dev/null
+++ b/drm/mediadrm/plugins/clearkey/hidl/AesCtrDecryptor.cpp
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2018 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.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "hidl_ClearkeyDecryptor"
+#include <utils/Log.h>
+
+#include <openssl/aes.h>
+
+#include "AesCtrDecryptor.h"
+#include "ClearKeyTypes.h"
+
+namespace android {
+namespace hardware {
+namespace drm {
+namespace V1_1 {
+namespace clearkey {
+
+using ::android::hardware::drm::V1_0::SubSample;
+using ::android::hardware::drm::V1_0::Status;
+
+static const size_t kBlockBitCount = kBlockSize * 8;
+
+Status AesCtrDecryptor::decrypt(
+ const std::vector<uint8_t>& key,
+ const Iv iv, const uint8_t* source,
+ uint8_t* destination,
+ const std::vector<SubSample> subSamples,
+ size_t numSubSamples,
+ size_t* bytesDecryptedOut) {
+ uint32_t blockOffset = 0;
+ uint8_t previousEncryptedCounter[kBlockSize];
+ memset(previousEncryptedCounter, 0, kBlockSize);
+
+ if (key.size() != kBlockSize || (sizeof(Iv) / sizeof(uint8_t)) != kBlockSize) {
+ android_errorWriteLog(0x534e4554, "63982768");
+ return Status::ERROR_DRM_DECRYPT;
+ }
+
+ size_t offset = 0;
+ AES_KEY opensslKey;
+ AES_set_encrypt_key(key.data(), kBlockBitCount, &opensslKey);
+ Iv opensslIv;
+ memcpy(opensslIv, iv, sizeof(opensslIv));
+
+ for (size_t i = 0; i < numSubSamples; ++i) {
+ const SubSample& subSample = subSamples[i];
+
+ if (subSample.numBytesOfClearData > 0) {
+ memcpy(destination + offset, source + offset,
+ subSample.numBytesOfClearData);
+ offset += subSample.numBytesOfClearData;
+ }
+
+ if (subSample.numBytesOfEncryptedData > 0) {
+ AES_ctr128_encrypt(source + offset, destination + offset,
+ subSample.numBytesOfEncryptedData, &opensslKey,
+ opensslIv, previousEncryptedCounter,
+ &blockOffset);
+ offset += subSample.numBytesOfEncryptedData;
+ }
+ }
+
+ *bytesDecryptedOut = offset;
+ return Status::OK;
+}
+
+} // namespace clearkey
+} // namespace V1_1
+} // namespace drm
+} // namespace hardware
+} // namespace android
+
diff --git a/drm/mediadrm/plugins/clearkey/Android.bp b/drm/mediadrm/plugins/clearkey/hidl/Android.bp
similarity index 66%
copy from drm/mediadrm/plugins/clearkey/Android.bp
copy to drm/mediadrm/plugins/clearkey/hidl/Android.bp
index 4b7a63c..341d4f6 100644
--- a/drm/mediadrm/plugins/clearkey/Android.bp
+++ b/drm/mediadrm/plugins/clearkey/hidl/Android.bp
@@ -1,5 +1,5 @@
//
-// Copyright (C) 2014 The Android Open Source Project
+// Copyright (C) 2018 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.
@@ -14,12 +14,14 @@
// limitations under the License.
//
-cc_library_shared {
- name: "libdrmclearkeyplugin",
+cc_binary {
+ name: "android.hardware.drm@1.1-service.clearkey",
+ vendor: true,
srcs: [
"AesCtrDecryptor.cpp",
- "ClearKeyUUID.cpp",
+ "Base64.cpp",
+ "Buffer.cpp",
"CreatePluginFactories.cpp",
"CryptoFactory.cpp",
"CryptoPlugin.cpp",
@@ -29,29 +31,34 @@
"JsonWebKey.cpp",
"Session.cpp",
"SessionLibrary.cpp",
- "Utils.cpp",
+ "service.cpp",
],
- vendor: true,
- relative_install_path: "mediadrm",
+ relative_install_path: "hw",
cflags: ["-Wall", "-Werror"],
+ init_rc: ["android.hardware.drm@1.1-service.clearkey.rc"],
shared_libs: [
+ "android.hardware.drm@1.0",
+ "android.hardware.drm@1.1",
+ "libbase",
+ "libbinder",
"libcrypto",
+ "libhidlbase",
+ "libhidlmemory",
+ "libhidltransport",
"liblog",
- "libstagefright_foundation",
"libutils",
],
- static_libs: ["libjsmn"],
-
- include_dirs: [
- "frameworks/native/include",
- "frameworks/av/include",
+ static_libs: [
+ "libclearkeycommon",
+ "libjsmn",
],
- export_include_dirs: ["."],
+ local_include_dirs: ["include"],
+
export_static_lib_headers: ["libjsmn"],
sanitize: {
@@ -59,7 +66,3 @@
},
}
-//########################################################################
-// Build unit tests
-
-subdirs = ["tests"]
diff --git a/drm/mediadrm/plugins/clearkey/hidl/Base64.cpp b/drm/mediadrm/plugins/clearkey/hidl/Base64.cpp
new file mode 100644
index 0000000..c2ed751
--- /dev/null
+++ b/drm/mediadrm/plugins/clearkey/hidl/Base64.cpp
@@ -0,0 +1,175 @@
+/*
+ * Copyright (C) 2018 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 "Base64.h"
+
+#include <string>
+
+namespace android {
+namespace hardware {
+namespace drm {
+namespace V1_1 {
+namespace clearkey {
+
+sp<Buffer> decodeBase64(const std::string &s) {
+ size_t n = s.size();
+
+ if ((n % 4) != 0) {
+ return nullptr;
+ }
+
+ size_t padding = 0;
+ if (n >= 1 && s.c_str()[n - 1] == '=') {
+ padding = 1;
+
+ if (n >= 2 && s.c_str()[n - 2] == '=') {
+ padding = 2;
+
+ if (n >= 3 && s.c_str()[n - 3] == '=') {
+ padding = 3;
+ }
+ }
+ }
+
+ // We divide first to avoid overflow. It's OK to do this because we
+ // already made sure that n % 4 == 0.
+ size_t outLen = (n / 4) * 3 - padding;
+
+ sp<Buffer> buffer = new Buffer(outLen);
+ uint8_t *out = buffer->data();
+ if (out == nullptr || buffer->size() < outLen) {
+ return nullptr;
+ }
+
+ size_t j = 0;
+ uint32_t accum = 0;
+ for (size_t i = 0; i < n; ++i) {
+ char c = s.c_str()[i];
+ unsigned value;
+ if (c >= 'A' && c <= 'Z') {
+ value = c - 'A';
+ } else if (c >= 'a' && c <= 'z') {
+ value = 26 + c - 'a';
+ } else if (c >= '0' && c <= '9') {
+ value = 52 + c - '0';
+ } else if (c == '+' || c == '-') {
+ value = 62;
+ } else if (c == '/' || c == '_') {
+ value = 63;
+ } else if (c != '=') {
+ return nullptr;
+ } else {
+ if (i < n - padding) {
+ return nullptr;
+ }
+
+ value = 0;
+ }
+
+ accum = (accum << 6) | value;
+
+ if (((i + 1) % 4) == 0) {
+ if (j < outLen) { out[j++] = (accum >> 16); }
+ if (j < outLen) { out[j++] = (accum >> 8) & 0xff; }
+ if (j < outLen) { out[j++] = accum & 0xff; }
+
+ accum = 0;
+ }
+ }
+
+ return buffer;
+}
+
+static char encode6Bit(unsigned x) {
+ if (x <= 25) {
+ return 'A' + x;
+ } else if (x <= 51) {
+ return 'a' + x - 26;
+ } else if (x <= 61) {
+ return '0' + x - 52;
+ } else if (x == 62) {
+ return '+';
+ } else {
+ return '/';
+ }
+}
+
+void encodeBase64(const void *_data, size_t size, std::string *out) {
+ out->clear();
+
+ const uint8_t *data = (const uint8_t *)_data;
+
+ size_t i;
+ for (i = 0; i < (size / 3) * 3; i += 3) {
+ uint8_t x1 = data[i];
+ uint8_t x2 = data[i + 1];
+ uint8_t x3 = data[i + 2];
+
+ out->push_back(encode6Bit(x1 >> 2));
+ out->push_back(encode6Bit((x1 << 4 | x2 >> 4) & 0x3f));
+ out->push_back(encode6Bit((x2 << 2 | x3 >> 6) & 0x3f));
+ out->push_back(encode6Bit(x3 & 0x3f));
+ }
+ switch (size % 3) {
+ case 0:
+ break;
+ case 2:
+ {
+ uint8_t x1 = data[i];
+ uint8_t x2 = data[i + 1];
+ out->push_back(encode6Bit(x1 >> 2));
+ out->push_back(encode6Bit((x1 << 4 | x2 >> 4) & 0x3f));
+ out->push_back(encode6Bit((x2 << 2) & 0x3f));
+ out->push_back('=');
+ break;
+ }
+ default:
+ {
+ uint8_t x1 = data[i];
+ out->push_back(encode6Bit(x1 >> 2));
+ out->push_back(encode6Bit((x1 << 4) & 0x3f));
+ out->append("==");
+ break;
+ }
+ }
+}
+
+void encodeBase64Url(const void *_data, size_t size, std::string *out) {
+ encodeBase64(_data, size, out);
+
+ if ((std::string::npos != out->find("+")) ||
+ (std::string::npos != out->find("/"))) {
+ size_t outLen = out->size();
+ char *base64url = new char[outLen];
+ for (size_t i = 0; i < outLen; ++i) {
+ if (out->c_str()[i] == '+')
+ base64url[i] = '-';
+ else if (out->c_str()[i] == '/')
+ base64url[i] = '_';
+ else
+ base64url[i] = out->c_str()[i];
+ }
+
+ out->assign(base64url, outLen);
+ delete[] base64url;
+ }
+}
+
+} // namespace clearkey
+} // namespace V1_1
+} // namespace drm
+} // namespace hardware
+} // namespace android
diff --git a/drm/mediadrm/plugins/clearkey/hidl/Buffer.cpp b/drm/mediadrm/plugins/clearkey/hidl/Buffer.cpp
new file mode 100644
index 0000000..e58f58a
--- /dev/null
+++ b/drm/mediadrm/plugins/clearkey/hidl/Buffer.cpp
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2018 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 "Buffer.h"
+
+#include <android/hardware/drm/1.0/types.h>
+
+namespace android {
+namespace hardware {
+namespace drm {
+namespace V1_1 {
+namespace clearkey {
+
+Buffer::Buffer(size_t capacity)
+ : mRangeOffset(0),
+ mOwnsData(true) {
+ mData = malloc(capacity);
+ if (mData == nullptr) {
+ mCapacity = 0;
+ mRangeLength = 0;
+ } else {
+ mCapacity = capacity;
+ mRangeLength = capacity;
+ }
+}
+
+Buffer::~Buffer() {
+ if (mOwnsData) {
+ if (mData != nullptr) {
+ free(mData);
+ mData = nullptr;
+ }
+ }
+}
+
+} // namespace clearkey
+} // namespace V1_1
+} // namespace drm
+} // namespace hardware
+} // namespace android
diff --git a/drm/mediadrm/plugins/clearkey/hidl/CreatePluginFactories.cpp b/drm/mediadrm/plugins/clearkey/hidl/CreatePluginFactories.cpp
new file mode 100644
index 0000000..1ba5c6a
--- /dev/null
+++ b/drm/mediadrm/plugins/clearkey/hidl/CreatePluginFactories.cpp
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2018 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 "CreatePluginFactories.h"
+
+#include "CryptoFactory.h"
+#include "DrmFactory.h"
+
+namespace android {
+namespace hardware {
+namespace drm {
+namespace V1_1 {
+namespace clearkey {
+
+extern "C" {
+
+IDrmFactory* createDrmFactory() {
+ return new DrmFactory();
+}
+
+ICryptoFactory* createCryptoFactory() {
+ return new CryptoFactory();
+}
+
+} // extern "C"
+
+} // namespace clearkey
+} // namespace V1_1
+} // namespace drm
+} // namespace hardware
+} // namespace android
diff --git a/drm/mediadrm/plugins/clearkey/hidl/CryptoFactory.cpp b/drm/mediadrm/plugins/clearkey/hidl/CryptoFactory.cpp
new file mode 100644
index 0000000..0848cef
--- /dev/null
+++ b/drm/mediadrm/plugins/clearkey/hidl/CryptoFactory.cpp
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2018 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.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "hidl_ClearKeyCryptoFactory"
+#include <utils/Log.h>
+
+#include "CryptoFactory.h"
+
+#include "ClearKeyUUID.h"
+#include "CryptoPlugin.h"
+#include "TypeConvert.h"
+
+namespace android {
+namespace hardware {
+namespace drm {
+namespace V1_1 {
+namespace clearkey {
+
+Return<bool> CryptoFactory::isCryptoSchemeSupported(
+ const hidl_array<uint8_t, 16> &uuid)
+{
+ return clearkeydrm::isClearKeyUUID(uuid.data());
+}
+
+Return<void> CryptoFactory::createPlugin(
+ const hidl_array<uint8_t, 16> &uuid,
+ const hidl_vec<uint8_t> &initData,
+ createPlugin_cb _hidl_cb) {
+
+ if (!isCryptoSchemeSupported(uuid.data())) {
+ ALOGE("Clearkey Drm HAL: failed to create clearkey plugin, " \
+ "invalid crypto scheme");
+ _hidl_cb(Status::BAD_VALUE, nullptr);
+ return Void();
+ }
+
+ CryptoPlugin *cryptoPlugin = new CryptoPlugin(initData);
+ Status status = cryptoPlugin->getInitStatus();
+ if (status == Status::OK) {
+ _hidl_cb(Status::OK, cryptoPlugin);
+ } else {
+ delete cryptoPlugin;
+ _hidl_cb(status, nullptr);
+ }
+ return Void();
+}
+
+} // namespace clearkey
+} // namespace V1_1
+} // namespace drm
+} // namespace hardware
+} // namespace android
+
diff --git a/drm/mediadrm/plugins/clearkey/hidl/CryptoPlugin.cpp b/drm/mediadrm/plugins/clearkey/hidl/CryptoPlugin.cpp
new file mode 100644
index 0000000..f33f94e
--- /dev/null
+++ b/drm/mediadrm/plugins/clearkey/hidl/CryptoPlugin.cpp
@@ -0,0 +1,185 @@
+/*
+ * Copyright (C) 2018 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.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "hidl_ClearKeyCryptoPlugin"
+#include <utils/Log.h>
+
+#include "CryptoPlugin.h"
+#include "SessionLibrary.h"
+#include "TypeConvert.h"
+
+#include <hidlmemory/mapping.h>
+
+namespace android {
+namespace hardware {
+namespace drm {
+namespace V1_1 {
+namespace clearkey {
+
+using ::android::hardware::drm::V1_0::BufferType;
+
+Return<void> CryptoPlugin::setSharedBufferBase(
+ const hidl_memory& base, uint32_t bufferId) {
+ sp<IMemory> hidlMemory = mapMemory(base);
+ ALOGE_IF(hidlMemory == nullptr, "mapMemory returns nullptr");
+
+ // allow mapMemory to return nullptr
+ mSharedBufferMap[bufferId] = hidlMemory;
+ return Void();
+}
+
+// Returns negative values for error code and positive values for the size of
+// decrypted data. In theory, the output size can be larger than the input
+// size, but in practice this will never happen for AES-CTR.
+Return<void> CryptoPlugin::decrypt(
+ bool secure,
+ const hidl_array<uint8_t, KEY_ID_SIZE>& keyId,
+ const hidl_array<uint8_t, KEY_IV_SIZE>& iv,
+ Mode mode,
+ const Pattern& pattern,
+ const hidl_vec<SubSample>& subSamples,
+ const SharedBuffer& source,
+ uint64_t offset,
+ const DestinationBuffer& destination,
+ decrypt_cb _hidl_cb) {
+ UNUSED(pattern);
+
+ if (secure) {
+ _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0,
+ "Secure decryption is not supported with ClearKey.");
+ return Void();
+ }
+
+ if (mSharedBufferMap.find(source.bufferId) == mSharedBufferMap.end()) {
+ _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0,
+ "source decrypt buffer base not set");
+ return Void();
+ }
+
+ if (destination.type == BufferType::SHARED_MEMORY) {
+ const SharedBuffer& dest = destination.nonsecureMemory;
+ if (mSharedBufferMap.find(dest.bufferId) == mSharedBufferMap.end()) {
+ _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0,
+ "destination decrypt buffer base not set");
+ return Void();
+ }
+ }
+
+ sp<IMemory> sourceBase = mSharedBufferMap[source.bufferId];
+ if (sourceBase == nullptr) {
+ _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0, "source is a nullptr");
+ return Void();
+ }
+
+ if (source.offset + offset + source.size > sourceBase->getSize()) {
+ _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0, "invalid buffer size");
+ return Void();
+ }
+
+ uint8_t *base = static_cast<uint8_t *>
+ (static_cast<void *>(sourceBase->getPointer()));
+ uint8_t* srcPtr = static_cast<uint8_t *>(base + source.offset + offset);
+ void* destPtr = NULL;
+ if (destination.type == BufferType::SHARED_MEMORY) {
+ const SharedBuffer& destBuffer = destination.nonsecureMemory;
+ sp<IMemory> destBase = mSharedBufferMap[destBuffer.bufferId];
+ if (destBase == nullptr) {
+ _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0, "destination is a nullptr");
+ return Void();
+ }
+
+ if (destBuffer.offset + destBuffer.size > destBase->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);
+ }
+
+ // Calculate the output buffer size and determine if any subsamples are
+ // encrypted.
+ size_t destSize = 0;
+ bool haveEncryptedSubsamples = false;
+ for (size_t i = 0; i < subSamples.size(); i++) {
+ const SubSample &subSample = subSamples[i];
+ destSize += subSample.numBytesOfClearData;
+ destSize += subSample.numBytesOfEncryptedData;
+ if (subSample.numBytesOfEncryptedData > 0) {
+ haveEncryptedSubsamples = true;
+ }
+ }
+
+ if (mode == Mode::UNENCRYPTED) {
+ if (haveEncryptedSubsamples) {
+ _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0,
+ "Encrypted subsamples found in allegedly unencrypted data.");
+ return Void();
+ }
+
+ size_t offset = 0;
+ for (size_t i = 0; i < subSamples.size(); ++i) {
+ const SubSample& subSample = subSamples[i];
+ if (subSample.numBytesOfClearData != 0) {
+ memcpy(reinterpret_cast<uint8_t*>(destPtr) + offset,
+ reinterpret_cast<const uint8_t*>(srcPtr) + offset,
+ subSample.numBytesOfClearData);
+ offset += subSample.numBytesOfClearData;
+ }
+ }
+
+ _hidl_cb(Status::OK, static_cast<ssize_t>(offset), "");
+ return Void();
+ } else if (mode == Mode::AES_CTR) {
+ size_t bytesDecrypted;
+ Status res = mSession->decrypt(keyId.data(), iv.data(), srcPtr,
+ static_cast<uint8_t*>(destPtr), toVector(subSamples), &bytesDecrypted);
+ if (res == Status::OK) {
+ _hidl_cb(Status::OK, static_cast<ssize_t>(bytesDecrypted), "");
+ return Void();
+ } else {
+ _hidl_cb(Status::ERROR_DRM_DECRYPT, static_cast<ssize_t>(res),
+ "Decryption Error");
+ return Void();
+ }
+ } else {
+ _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0,
+ "Selected encryption mode is not supported by the ClearKey DRM Plugin.");
+ return Void();
+ }
+}
+
+Return<Status> CryptoPlugin::setMediaDrmSession(
+ const hidl_vec<uint8_t>& sessionId) {
+ if (!sessionId.size()) {
+ mSession = nullptr;
+ } else {
+ mSession = SessionLibrary::get()->findSession(sessionId);
+ if (!mSession.get()) {
+ return Status::ERROR_DRM_SESSION_NOT_OPENED;
+ }
+ }
+ return Status::OK;
+}
+
+} // namespace clearkey
+} // namespace V1_1
+} // namespace drm
+} // namespace hardware
+} // namespace android
diff --git a/drm/mediadrm/plugins/clearkey/hidl/DrmFactory.cpp b/drm/mediadrm/plugins/clearkey/hidl/DrmFactory.cpp
new file mode 100644
index 0000000..77557f9
--- /dev/null
+++ b/drm/mediadrm/plugins/clearkey/hidl/DrmFactory.cpp
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2018 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.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "hidl_ClearKeyDrmFactory"
+#include <utils/Log.h>
+
+#include <utils/Errors.h>
+
+#include "DrmFactory.h"
+
+#include "DrmPlugin.h"
+#include "ClearKeyUUID.h"
+#include "MimeType.h"
+#include "SessionLibrary.h"
+
+namespace android {
+namespace hardware {
+namespace drm {
+namespace V1_1 {
+namespace clearkey {
+
+using ::android::hardware::drm::V1_0::Status;
+using ::android::hardware::Void;
+
+Return<bool> DrmFactory::isCryptoSchemeSupported(
+ const hidl_array<uint8_t, 16>& uuid) {
+ return clearkeydrm::isClearKeyUUID(uuid.data());
+}
+
+Return<bool> DrmFactory::isContentTypeSupported(const hidl_string &mimeType) {
+ // This should match the mimeTypes handed by InitDataParser.
+ return mimeType == kIsoBmffVideoMimeType ||
+ mimeType == kIsoBmffAudioMimeType ||
+ mimeType == kCencInitDataFormat ||
+ mimeType == kWebmVideoMimeType ||
+ mimeType == kWebmAudioMimeType ||
+ mimeType == kWebmInitDataFormat;
+}
+
+Return<void> DrmFactory::createPlugin(
+ const hidl_array<uint8_t, 16>& uuid,
+ const hidl_string& appPackageName,
+ createPlugin_cb _hidl_cb) {
+ UNUSED(appPackageName);
+
+ DrmPlugin *plugin = NULL;
+ if (!isCryptoSchemeSupported(uuid.data())) {
+ ALOGE("Clear key Drm HAL: failed to create drm plugin, " \
+ "invalid crypto scheme");
+ _hidl_cb(Status::BAD_VALUE, plugin);
+ return Void();
+ }
+
+ plugin = new DrmPlugin(SessionLibrary::get());
+ _hidl_cb(Status::OK, plugin);
+ return Void();
+}
+
+} // namespace clearkey
+} // namespace V1_1
+} // namespace drm
+} // namespace hardware
+} // namespace android
diff --git a/drm/mediadrm/plugins/clearkey/hidl/DrmPlugin.cpp b/drm/mediadrm/plugins/clearkey/hidl/DrmPlugin.cpp
new file mode 100644
index 0000000..9506cd1
--- /dev/null
+++ b/drm/mediadrm/plugins/clearkey/hidl/DrmPlugin.cpp
@@ -0,0 +1,371 @@
+/*
+ * Copyright (C) 2018 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.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "hidl_ClearKeyPlugin"
+#include <utils/Log.h>
+
+#include <stdio.h>
+
+#include "DrmPlugin.h"
+#include "ClearKeyDrmProperties.h"
+#include "Session.h"
+#include "TypeConvert.h"
+
+namespace {
+const std::string kStreaming("Streaming");
+const std::string kOffline("Offline");
+const std::string kTrue("True");
+
+const std::string kQueryKeyLicenseType("LicenseType");
+ // Value: "Streaming" or "Offline"
+const std::string kQueryKeyPlayAllowed("PlayAllowed");
+ // Value: "True" or "False"
+const std::string kQueryKeyRenewAllowed("RenewAllowed");
+ // Value: "True" or "False"
+};
+
+namespace android {
+namespace hardware {
+namespace drm {
+namespace V1_1 {
+namespace clearkey {
+
+DrmPlugin::DrmPlugin(SessionLibrary* sessionLibrary)
+ : mSessionLibrary(sessionLibrary) {
+ mPlayPolicy.clear();
+ initProperties();
+
+}
+
+void DrmPlugin::initProperties() {
+ mStringProperties.clear();
+ mStringProperties[kVendorKey] = kVendorValue;
+ mStringProperties[kVersionKey] = kVersionValue;
+ mStringProperties[kPluginDescriptionKey] = kPluginDescriptionValue;
+ mStringProperties[kAlgorithmsKey] = kAlgorithmsValue;
+ mStringProperties[kListenerTestSupportKey] = kListenerTestSupportValue;
+
+ std::vector<uint8_t> valueVector;
+ valueVector.clear();
+ valueVector.insert(valueVector.end(),
+ kTestDeviceIdData, kTestDeviceIdData + sizeof(kTestDeviceIdData) / sizeof(uint8_t));
+ mByteArrayProperties[kDeviceIdKey] = valueVector;
+
+ valueVector.clear();
+ valueVector.insert(valueVector.end(),
+ kMetricsData, kMetricsData + sizeof(kMetricsData) / sizeof(uint8_t));
+ mByteArrayProperties[kMetricsKey] = valueVector;
+}
+
+Return<void> DrmPlugin::openSession(openSession_cb _hidl_cb) {
+ sp<Session> session = mSessionLibrary->createSession();
+ std::vector<uint8_t> sessionId = session->sessionId();
+
+ setSecurityLevel(sessionId, SecurityLevel::SW_SECURE_CRYPTO);
+ _hidl_cb(Status::OK, toHidlVec(sessionId));
+ return Void();
+}
+
+Return<Status> DrmPlugin::closeSession(const hidl_vec<uint8_t>& sessionId) {
+ if (sessionId.size() == 0) {
+ return Status::BAD_VALUE;
+ }
+
+ sp<Session> session = mSessionLibrary->findSession(toVector(sessionId));
+ if (session.get()) {
+ mSessionLibrary->destroySession(session);
+ return Status::OK;
+ }
+ return Status::ERROR_DRM_SESSION_NOT_OPENED;
+}
+
+Return<void> DrmPlugin::getKeyRequest(
+ const hidl_vec<uint8_t>& scope,
+ const hidl_vec<uint8_t>& initData,
+ const hidl_string& mimeType,
+ KeyType keyType,
+ const hidl_vec<KeyValue>& optionalParameters,
+ getKeyRequest_cb _hidl_cb) {
+ UNUSED(optionalParameters);
+
+ if (scope.size() == 0) {
+ // Returns empty keyRequest, unknown keyType and empty defaultUrl
+ _hidl_cb(Status::BAD_VALUE, hidl_vec<uint8_t>(),
+ KeyRequestType::UNKNOWN, "");
+ return Void();
+ }
+
+ if (keyType != KeyType::STREAMING) {
+ _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, hidl_vec<uint8_t>(),
+ KeyRequestType::UNKNOWN, "");
+ return Void();
+ }
+
+ sp<Session> session = mSessionLibrary->findSession(toVector(scope));
+ if (!session.get()) {
+ _hidl_cb(Status::ERROR_DRM_SESSION_NOT_OPENED, hidl_vec<uint8_t>(),
+ KeyRequestType::UNKNOWN, "");
+ return Void();
+ }
+
+ std::vector<uint8_t> request;
+ Status status = session->getKeyRequest(initData, mimeType, &request);
+ _hidl_cb(status, toHidlVec(request), KeyRequestType::INITIAL, "");
+ return Void();
+}
+
+Return<void> DrmPlugin::getKeyRequest_1_1(
+ const hidl_vec<uint8_t>& scope,
+ const hidl_vec<uint8_t>& initData,
+ const hidl_string& mimeType,
+ KeyType keyType,
+ const hidl_vec<KeyValue>& optionalParameters,
+ getKeyRequest_1_1_cb _hidl_cb) {
+ hidl_string defaultUrl;
+ hidl_vec<uint8_t> request;
+ ::android::hardware::drm::V1_1::KeyRequestType requestType =
+ static_cast<::android::hardware::drm::V1_1::KeyRequestType>(KeyRequestType::UNKNOWN);
+ Status status = Status::OK;
+
+ defaultUrl.clear();
+ getKeyRequest(scope, initData, mimeType, keyType, optionalParameters,
+ [&](Status statusCode, const hidl_vec<uint8_t>& hResult,
+ KeyRequestType hKeyRequestType,
+ const hidl_string& hDefaultUrl) {
+ defaultUrl = hDefaultUrl;
+ request = hResult;
+ requestType = static_cast<::android::hardware::drm::V1_1::KeyRequestType>(hKeyRequestType);
+ status = statusCode;
+ });
+ _hidl_cb(status, request, requestType, defaultUrl);
+ return Void();
+}
+
+void DrmPlugin::setPlayPolicy() {
+ mPlayPolicy.clear();
+
+ KeyValue policy;
+ policy.key = kQueryKeyLicenseType;
+ policy.value = kStreaming;
+ mPlayPolicy.push_back(policy);
+
+ policy.key = kQueryKeyPlayAllowed;
+ policy.value = kTrue;
+ mPlayPolicy.push_back(policy);
+
+ policy.key = kQueryKeyRenewAllowed;
+ mPlayPolicy.push_back(policy);
+}
+
+Return<void> DrmPlugin::provideKeyResponse(
+ const hidl_vec<uint8_t>& scope,
+ const hidl_vec<uint8_t>& response,
+ provideKeyResponse_cb _hidl_cb) {
+ if (scope.size() == 0 || response.size() == 0) {
+ // Returns empty keySetId
+ _hidl_cb(Status::BAD_VALUE, hidl_vec<uint8_t>());
+ return Void();
+ }
+ sp<Session> session = mSessionLibrary->findSession(toVector(scope));
+ if (!session.get()) {
+ _hidl_cb(Status::ERROR_DRM_SESSION_NOT_OPENED, hidl_vec<uint8_t>());
+ return Void();
+ }
+
+ setPlayPolicy();
+ std::vector<uint8_t> keySetId;
+ Status status = session->provideKeyResponse(response);
+ if (status == Status::OK) {
+ // This is for testing AMediaDrm_setOnEventListener only.
+ sendEvent(EventType::VENDOR_DEFINED, 0, scope);
+ keySetId.clear();
+ }
+
+ // Returns status and empty keySetId
+ _hidl_cb(status, toHidlVec(keySetId));
+ return Void();
+}
+
+Return<void> DrmPlugin::getPropertyString(
+ const hidl_string& propertyName, getPropertyString_cb _hidl_cb) {
+ std::string name(propertyName.c_str());
+ std::string value;
+
+ if (name == "vendor") {
+ value = "Google";
+ } else if (name == "version") {
+ value = "1.1";
+ } else if (name == "description") {
+ value = "ClearKey CDM";
+ } else if (name == "algorithms") {
+ value = "";
+ } else if (name == "listenerTestSupport") {
+ value = mStringProperties[name];
+ } else {
+ ALOGE("App requested unknown string property %s", name.c_str());
+ _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, "");
+ return Void();
+ }
+ _hidl_cb(Status::OK, value.c_str());
+ return Void();
+}
+
+Return<void> DrmPlugin::getPropertyByteArray(
+ const hidl_string& propertyName, getPropertyByteArray_cb _hidl_cb) {
+ std::map<std::string, std::vector<uint8_t> >::iterator itr =
+ mByteArrayProperties.find(std::string(propertyName.c_str()));
+ if (itr == mByteArrayProperties.end()) {
+ ALOGE("App requested unknown property: %s", propertyName.c_str());
+ _hidl_cb(Status::BAD_VALUE, std::vector<uint8_t>());
+ return Void();
+ }
+ _hidl_cb(Status::OK, itr->second);
+ return Void();
+
+}
+
+Return<Status> DrmPlugin::setPropertyString(
+ const hidl_string& name, const hidl_string& value) {
+ std::string immutableKeys;
+ immutableKeys.append(kAlgorithmsKey + ",");
+ immutableKeys.append(kPluginDescriptionKey + ",");
+ immutableKeys.append(kVendorKey + ",");
+ immutableKeys.append(kVersionKey + ",");
+
+ std::string key = std::string(name.c_str());
+ if (immutableKeys.find(key) != std::string::npos) {
+ ALOGD("Cannot set immutable property: %s", key.c_str());
+ return Status::BAD_VALUE;
+ }
+
+ std::map<std::string, std::string>::iterator itr =
+ mStringProperties.find(key);
+ if (itr == mStringProperties.end()) {
+ ALOGE("Cannot set undefined property string, key=%s", key.c_str());
+ return Status::BAD_VALUE;
+ }
+
+ mStringProperties[key] = std::string(value.c_str());
+ return Status::OK;
+}
+
+Return<Status> DrmPlugin::setPropertyByteArray(
+ const hidl_string& name, const hidl_vec<uint8_t>& value) {
+ UNUSED(value);
+ if (name == kDeviceIdKey) {
+ ALOGD("Cannot set immutable property: %s", name.c_str());
+ return Status::BAD_VALUE;
+ }
+
+ // Setting of undefined properties is not supported
+ ALOGE("Failed to set property byte array, key=%s", name.c_str());
+ return Status::ERROR_DRM_CANNOT_HANDLE;
+}
+
+Return<void> DrmPlugin::queryKeyStatus(
+ const hidl_vec<uint8_t>& sessionId,
+ queryKeyStatus_cb _hidl_cb) {
+
+ if (sessionId.size() == 0) {
+ // Returns empty key status KeyValue pair
+ _hidl_cb(Status::BAD_VALUE, hidl_vec<KeyValue>());
+ return Void();
+ }
+
+ std::vector<KeyValue> infoMapVec;
+ infoMapVec.clear();
+
+ KeyValue keyValuePair;
+ for (size_t i = 0; i < mPlayPolicy.size(); ++i) {
+ keyValuePair.key = mPlayPolicy[i].key;
+ keyValuePair.value = mPlayPolicy[i].value;
+ infoMapVec.push_back(keyValuePair);
+ }
+ _hidl_cb(Status::OK, toHidlVec(infoMapVec));
+ return Void();
+}
+
+Return<void> DrmPlugin::getNumberOfSessions(getNumberOfSessions_cb _hidl_cb) {
+ uint32_t currentSessions = mSessionLibrary->numOpenSessions();
+ uint32_t maxSessions = 10;
+ _hidl_cb(Status::OK, currentSessions, maxSessions);
+ return Void();
+}
+
+Return<void> DrmPlugin::getSecurityLevel(const hidl_vec<uint8_t>& sessionId,
+ getSecurityLevel_cb _hidl_cb) {
+ if (sessionId.size() == 0) {
+ _hidl_cb(Status::BAD_VALUE, SecurityLevel::UNKNOWN);
+ return Void();
+ }
+
+ std::vector<uint8_t> sid = toVector(sessionId);
+ sp<Session> session = mSessionLibrary->findSession(sid);
+ if (!session.get()) {
+ _hidl_cb(Status::ERROR_DRM_SESSION_NOT_OPENED, SecurityLevel::UNKNOWN);
+ return Void();
+ }
+
+ std::map<std::vector<uint8_t>, SecurityLevel>::iterator itr =
+ mSecurityLevel.find(sid);
+ if (itr == mSecurityLevel.end()) {
+ ALOGE("Session id not found");
+ _hidl_cb(Status::ERROR_DRM_INVALID_STATE, SecurityLevel::UNKNOWN);
+ return Void();
+ }
+
+ _hidl_cb(Status::OK, itr->second);
+ return Void();
+}
+
+Return<Status> DrmPlugin::setSecurityLevel(const hidl_vec<uint8_t>& sessionId,
+ SecurityLevel level) {
+ if (sessionId.size() == 0) {
+ ALOGE("Invalid empty session id");
+ return Status::BAD_VALUE;
+ }
+
+ if (level > SecurityLevel::HW_SECURE_ALL) {
+ ALOGE("Cannot set invalid security level");
+ return Status::BAD_VALUE;
+ }
+
+ std::vector<uint8_t> sid = toVector(sessionId);
+ sp<Session> session = mSessionLibrary->findSession(sid);
+ if (!session.get()) {
+ return Status::ERROR_DRM_SESSION_NOT_OPENED;
+ }
+
+ std::map<std::vector<uint8_t>, SecurityLevel>::iterator itr =
+ mSecurityLevel.find(sid);
+ if (itr != mSecurityLevel.end()) {
+ mSecurityLevel[sid] = level;
+ } else {
+ if (!mSecurityLevel.insert(
+ std::pair<std::vector<uint8_t>, SecurityLevel>(sid, level)).second) {
+ ALOGE("Failed to set security level");
+ return Status::ERROR_DRM_INVALID_STATE;
+ }
+ }
+ return Status::OK;
+}
+
+} // namespace clearkey
+} // namespace V1_1
+} // namespace drm
+} // namespace hardware
+} // namespace android
diff --git a/drm/mediadrm/plugins/clearkey/hidl/InitDataParser.cpp b/drm/mediadrm/plugins/clearkey/hidl/InitDataParser.cpp
new file mode 100644
index 0000000..e2bb651
--- /dev/null
+++ b/drm/mediadrm/plugins/clearkey/hidl/InitDataParser.cpp
@@ -0,0 +1,163 @@
+/*
+ * Copyright (C) 2018 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.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "hidl_InitDataParser"
+
+#include <algorithm>
+#include <utils/Log.h>
+
+#include "InitDataParser.h"
+
+#include "Base64.h"
+
+#include "ClearKeyUUID.h"
+#include "MimeType.h"
+#include "Utils.h"
+
+namespace android {
+namespace hardware {
+namespace drm {
+namespace V1_1 {
+namespace clearkey {
+
+namespace {
+ const size_t kKeyIdSize = 16;
+ const size_t kSystemIdSize = 16;
+}
+
+std::vector<uint8_t> StrToVector(const std::string& str) {
+ std::vector<uint8_t> vec(str.begin(), str.end());
+ return vec;
+}
+
+Status InitDataParser::parse(const std::vector<uint8_t>& initData,
+ const std::string& type,
+ std::vector<uint8_t>* licenseRequest) {
+ // Build a list of the key IDs
+ std::vector<const uint8_t*> keyIds;
+
+ if (type == kIsoBmffVideoMimeType ||
+ type == kIsoBmffAudioMimeType ||
+ type == kCencInitDataFormat) {
+ Status res = parsePssh(initData, &keyIds);
+ if (res != Status::OK) {
+ return res;
+ }
+ } else if (type == kWebmVideoMimeType ||
+ type == kWebmAudioMimeType ||
+ type == kWebmInitDataFormat) {
+ // WebM "init data" is just a single key ID
+ if (initData.size() != kKeyIdSize) {
+ return Status::ERROR_DRM_CANNOT_HANDLE;
+ }
+ keyIds.push_back(initData.data());
+ } else {
+ return Status::ERROR_DRM_CANNOT_HANDLE;
+ }
+
+ // Build the request
+ std::string requestJson = generateRequest(keyIds);
+ std::vector<uint8_t> requestJsonVec = StrToVector(requestJson);
+
+ licenseRequest->clear();
+ licenseRequest->insert(licenseRequest->end(), requestJsonVec.begin(), requestJsonVec.end());
+ return Status::OK;
+}
+
+Status InitDataParser::parsePssh(const std::vector<uint8_t>& initData,
+ std::vector<const uint8_t*>* keyIds) {
+ size_t readPosition = 0;
+
+ // Validate size field
+ uint32_t expectedSize = initData.size();
+ expectedSize = htonl(expectedSize);
+ if (memcmp(&initData[readPosition], &expectedSize,
+ sizeof(expectedSize)) != 0) {
+ return Status::ERROR_DRM_CANNOT_HANDLE;
+ }
+ readPosition += sizeof(expectedSize);
+
+ // Validate PSSH box identifier
+ const char psshIdentifier[4] = {'p', 's', 's', 'h'};
+ if (memcmp(&initData[readPosition], psshIdentifier,
+ sizeof(psshIdentifier)) != 0) {
+ return Status::ERROR_DRM_CANNOT_HANDLE;
+ }
+ readPosition += sizeof(psshIdentifier);
+
+ // Validate EME version number
+ const uint8_t psshVersion1[4] = {1, 0, 0, 0};
+ if (memcmp(&initData[readPosition], psshVersion1,
+ sizeof(psshVersion1)) != 0) {
+ return Status::ERROR_DRM_CANNOT_HANDLE;
+ }
+ readPosition += sizeof(psshVersion1);
+
+ // Validate system ID
+ if (!clearkeydrm::isClearKeyUUID(&initData[readPosition])) {
+ return Status::ERROR_DRM_CANNOT_HANDLE;
+ }
+ readPosition += kSystemIdSize;
+
+ // Read key ID count
+ uint32_t keyIdCount;
+ memcpy(&keyIdCount, &initData[readPosition], sizeof(keyIdCount));
+ keyIdCount = ntohl(keyIdCount);
+ readPosition += sizeof(keyIdCount);
+ if (readPosition + ((uint64_t)keyIdCount * kKeyIdSize) !=
+ initData.size() - sizeof(uint32_t)) {
+ return Status::ERROR_DRM_CANNOT_HANDLE;
+ }
+
+ // Calculate the key ID offsets
+ for (uint32_t i = 0; i < keyIdCount; ++i) {
+ size_t keyIdPosition = readPosition + (i * kKeyIdSize);
+ keyIds->push_back(&initData[keyIdPosition]);
+ }
+ return Status::OK;
+}
+
+std::string InitDataParser::generateRequest(const std::vector<const uint8_t*>& keyIds) {
+ const std::string kRequestPrefix("{\"kids\":[");
+ const std::string kRequestSuffix("],\"type\":\"temporary\"}");
+
+ std::string request(kRequestPrefix);
+ std::string encodedId;
+ for (size_t i = 0; i < keyIds.size(); ++i) {
+ encodedId.clear();
+ encodeBase64Url(keyIds[i], kKeyIdSize, &encodedId);
+ if (i != 0) {
+ request.append(",");
+ }
+ request.push_back('\"');
+ request.append(encodedId);
+ request.push_back('\"');
+ }
+ request.append(kRequestSuffix);
+
+ // Android's Base64 encoder produces padding. EME forbids padding.
+ const char kBase64Padding = '=';
+ request.erase(std::remove(request.begin(), request.end(), kBase64Padding), request.end());
+
+ return request;
+}
+
+} // namespace clearkey
+} // namespace V1_1
+} // namespace drm
+} // namespace hardware
+} // namespace android
diff --git a/drm/mediadrm/plugins/clearkey/hidl/JsonWebKey.cpp b/drm/mediadrm/plugins/clearkey/hidl/JsonWebKey.cpp
new file mode 100644
index 0000000..cccb41e
--- /dev/null
+++ b/drm/mediadrm/plugins/clearkey/hidl/JsonWebKey.cpp
@@ -0,0 +1,275 @@
+/*
+ * Copyright (C) 2018 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.
+ */
+#define LOG_TAG "hidl_JsonWebKey"
+
+#include <utils/Log.h>
+
+#include "JsonWebKey.h"
+
+#include "Base64.h"
+
+namespace {
+const std::string kKeysTag("keys");
+const std::string kKeyTypeTag("kty");
+const std::string kSymmetricKeyValue("oct");
+const std::string kKeyTag("k");
+const std::string kKeyIdTag("kid");
+const std::string kBase64Padding("=");
+}
+
+namespace android {
+namespace hardware {
+namespace drm {
+namespace V1_1 {
+namespace clearkey {
+
+JsonWebKey::JsonWebKey() {
+}
+
+JsonWebKey::~JsonWebKey() {
+}
+
+/*
+ * Parses a JSON Web Key Set string, initializes a KeyMap with key id:key
+ * pairs from the JSON Web Key Set. Both key ids and keys are base64url
+ * encoded. The KeyMap contains base64url decoded key id:key pairs.
+ *
+ * @return Returns false for errors, true for success.
+ */
+bool JsonWebKey::extractKeysFromJsonWebKeySet(const std::string& jsonWebKeySet,
+ KeyMap* keys) {
+
+ keys->clear();
+
+ if (!parseJsonWebKeySet(jsonWebKeySet, &mJsonObjects)) {
+ return false;
+ }
+
+ // mJsonObjects[0] contains the entire JSON Web Key Set, including
+ // all the base64 encoded keys. Each key is also stored separately as
+ // a JSON object in mJsonObjects[1..n] where n is the total
+ // number of keys in the set.
+ if (!isJsonWebKeySet(mJsonObjects[0])) {
+ return false;
+ }
+
+ std::string encodedKey, encodedKeyId;
+ std::vector<uint8_t> decodedKey, decodedKeyId;
+
+ // mJsonObjects[1] contains the first JSON Web Key in the set
+ for (size_t i = 1; i < mJsonObjects.size(); ++i) {
+ encodedKeyId.clear();
+ encodedKey.clear();
+
+ if (!parseJsonObject(mJsonObjects[i], &mTokens))
+ return false;
+
+ if (findKey(mJsonObjects[i], &encodedKeyId, &encodedKey)) {
+ if (encodedKeyId.empty() || encodedKey.empty()) {
+ ALOGE("Must have both key id and key in the JsonWebKey set.");
+ continue;
+ }
+
+ if (!decodeBase64String(encodedKeyId, &decodedKeyId)) {
+ ALOGE("Failed to decode key id(%s)", encodedKeyId.c_str());
+ continue;
+ }
+
+ if (!decodeBase64String(encodedKey, &decodedKey)) {
+ ALOGE("Failed to decode key(%s)", encodedKey.c_str());
+ continue;
+ }
+
+ keys->insert(std::pair<std::vector<uint8_t>,
+ std::vector<uint8_t> >(decodedKeyId, decodedKey));
+ }
+ }
+ return true;
+}
+
+bool JsonWebKey::decodeBase64String(const std::string& encodedText,
+ std::vector<uint8_t>* decodedText) {
+
+ decodedText->clear();
+
+ // encodedText should not contain padding characters as per EME spec.
+ if (encodedText.find(kBase64Padding) != std::string::npos) {
+ return false;
+ }
+
+ // Since decodeBase64() requires padding characters,
+ // add them so length of encodedText is exactly a multiple of 4.
+ int remainder = encodedText.length() % 4;
+ std::string paddedText(encodedText);
+ if (remainder > 0) {
+ for (int i = 0; i < 4 - remainder; ++i) {
+ paddedText.append(kBase64Padding);
+ }
+ }
+
+ sp<Buffer> buffer = decodeBase64(paddedText);
+ if (buffer == nullptr) {
+ ALOGE("Malformed base64 encoded content found.");
+ return false;
+ }
+
+ decodedText->insert(decodedText->end(), buffer->base(), buffer->base() + buffer->size());
+ return true;
+}
+
+bool JsonWebKey::findKey(const std::string& jsonObject, std::string* keyId,
+ std::string* encodedKey) {
+
+ std::string key, value;
+
+ // Only allow symmetric key, i.e. "kty":"oct" pair.
+ if (jsonObject.find(kKeyTypeTag) != std::string::npos) {
+ findValue(kKeyTypeTag, &value);
+ if (0 != value.compare(kSymmetricKeyValue))
+ return false;
+ }
+
+ if (jsonObject.find(kKeyIdTag) != std::string::npos) {
+ findValue(kKeyIdTag, keyId);
+ }
+
+ if (jsonObject.find(kKeyTag) != std::string::npos) {
+ findValue(kKeyTag, encodedKey);
+ }
+ return true;
+}
+
+void JsonWebKey::findValue(const std::string &key, std::string* value) {
+ value->clear();
+ const char* valueToken;
+ for (std::vector<std::string>::const_iterator nextToken = mTokens.begin();
+ nextToken != mTokens.end(); ++nextToken) {
+ if (0 == (*nextToken).compare(key)) {
+ if (nextToken + 1 == mTokens.end())
+ break;
+ valueToken = (*(nextToken + 1)).c_str();
+ value->assign(valueToken);
+ nextToken++;
+ break;
+ }
+ }
+}
+
+bool JsonWebKey::isJsonWebKeySet(const std::string& jsonObject) const {
+ if (jsonObject.find(kKeysTag) == std::string::npos) {
+ ALOGE("JSON Web Key does not contain keys.");
+ return false;
+ }
+ return true;
+}
+
+/*
+ * Parses a JSON objects string and initializes a vector of tokens.
+ *
+ * @return Returns false for errors, true for success.
+ */
+bool JsonWebKey::parseJsonObject(const std::string& jsonObject,
+ std::vector<std::string>* tokens) {
+ jsmn_parser parser;
+
+ jsmn_init(&parser);
+ int numTokens = jsmn_parse(&parser,
+ jsonObject.c_str(), jsonObject.size(), nullptr, 0);
+ if (numTokens < 0) {
+ ALOGE("Parser returns error code=%d", numTokens);
+ return false;
+ }
+
+ unsigned int jsmnTokensSize = numTokens * sizeof(jsmntok_t);
+ mJsmnTokens.clear();
+ mJsmnTokens.resize(jsmnTokensSize);
+
+ jsmn_init(&parser);
+ int status = jsmn_parse(&parser, jsonObject.c_str(),
+ jsonObject.size(), mJsmnTokens.data(), numTokens);
+ if (status < 0) {
+ ALOGE("Parser returns error code=%d", status);
+ return false;
+ }
+
+ tokens->clear();
+ std::string token;
+ const char *pjs;
+ for (int j = 0; j < numTokens; ++j) {
+ pjs = jsonObject.c_str() + mJsmnTokens[j].start;
+ if (mJsmnTokens[j].type == JSMN_STRING ||
+ mJsmnTokens[j].type == JSMN_PRIMITIVE) {
+ token.assign(pjs, mJsmnTokens[j].end - mJsmnTokens[j].start);
+ tokens->push_back(token);
+ }
+ }
+ return true;
+}
+
+/*
+ * Parses JSON Web Key Set string and initializes a vector of JSON objects.
+ *
+ * @return Returns false for errors, true for success.
+ */
+bool JsonWebKey::parseJsonWebKeySet(const std::string& jsonWebKeySet,
+ std::vector<std::string>* jsonObjects) {
+ if (jsonWebKeySet.empty()) {
+ ALOGE("Empty JSON Web Key");
+ return false;
+ }
+
+ // The jsmn parser only supports unicode encoding.
+ jsmn_parser parser;
+
+ // Computes number of tokens. A token marks the type, offset in
+ // the original string.
+ jsmn_init(&parser);
+ int numTokens = jsmn_parse(&parser,
+ jsonWebKeySet.c_str(), jsonWebKeySet.size(), nullptr, 0);
+ if (numTokens < 0) {
+ ALOGE("Parser returns error code=%d", numTokens);
+ return false;
+ }
+
+ unsigned int jsmnTokensSize = numTokens * sizeof(jsmntok_t);
+ mJsmnTokens.resize(jsmnTokensSize);
+
+ jsmn_init(&parser);
+ int status = jsmn_parse(&parser, jsonWebKeySet.c_str(),
+ jsonWebKeySet.size(), mJsmnTokens.data(), numTokens);
+ if (status < 0) {
+ ALOGE("Parser returns error code=%d", status);
+ return false;
+ }
+
+ std::string token;
+ const char *pjs;
+ for (int i = 0; i < numTokens; ++i) {
+ pjs = jsonWebKeySet.c_str() + mJsmnTokens[i].start;
+ if (mJsmnTokens[i].type == JSMN_OBJECT) {
+ token.assign(pjs, mJsmnTokens[i].end - mJsmnTokens[i].start);
+ jsonObjects->push_back(token);
+ }
+ }
+ return true;
+}
+
+} // namespace clearkey
+} // namespace V1_1
+} // namespace drm
+} // namespace hardware
+} // namespace android
+
diff --git a/drm/mediadrm/plugins/clearkey/hidl/Session.cpp b/drm/mediadrm/plugins/clearkey/hidl/Session.cpp
new file mode 100644
index 0000000..07c9269
--- /dev/null
+++ b/drm/mediadrm/plugins/clearkey/hidl/Session.cpp
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2018 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.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "hidl_ClearKeySession"
+#include <utils/Log.h>
+
+#include "Session.h"
+#include "Utils.h"
+
+#include "AesCtrDecryptor.h"
+#include "InitDataParser.h"
+#include "JsonWebKey.h"
+
+namespace android {
+namespace hardware {
+namespace drm {
+namespace V1_1 {
+namespace clearkey {
+
+using ::android::hardware::drm::V1_0::KeyValue;
+using ::android::hardware::drm::V1_0::Status;
+using ::android::hardware::drm::V1_0::SubSample;
+using ::android::hardware::Return;
+using ::android::sp;
+
+using android::Mutex;
+
+Status Session::getKeyRequest(
+ const std::vector<uint8_t>& initData,
+ const std::string& mimeType,
+ std::vector<uint8_t>* keyRequest) const {
+ InitDataParser parser;
+ return parser.parse(initData, mimeType, keyRequest);
+}
+
+Status Session::provideKeyResponse(const std::vector<uint8_t>& response) {
+ std::string responseString(
+ reinterpret_cast<const char*>(response.data()), response.size());
+ KeyMap keys;
+
+ Mutex::Autolock lock(mMapLock);
+ JsonWebKey parser;
+ if (parser.extractKeysFromJsonWebKeySet(responseString, &keys)) {
+ for (auto &key : keys) {
+ std::string first(key.first.begin(), key.first.end());
+ std::string second(key.second.begin(), key.second.end());
+ mKeyMap.insert(std::pair<std::vector<uint8_t>,
+ std::vector<uint8_t> >(key.first, key.second));
+ }
+ return Status::OK;
+ } else {
+ return Status::ERROR_DRM_UNKNOWN;
+ }
+}
+
+Status Session::decrypt(
+ const KeyId keyId, const Iv iv, const uint8_t* srcPtr,
+ uint8_t* destPtr, const std::vector<SubSample> subSamples,
+ size_t* bytesDecryptedOut) {
+ Mutex::Autolock lock(mMapLock);
+
+ std::vector<uint8_t> keyIdVector;
+ keyIdVector.clear();
+ keyIdVector.insert(keyIdVector.end(), keyId, keyId + kBlockSize);
+ std::map<std::vector<uint8_t>, std::vector<uint8_t> >::iterator itr;
+ itr = mKeyMap.find(keyIdVector);
+ if (itr == mKeyMap.end()) {
+ return Status::ERROR_DRM_NO_LICENSE;
+ }
+
+ AesCtrDecryptor decryptor;
+ return decryptor.decrypt(
+ itr->second /*key*/, iv, srcPtr, destPtr, subSamples,
+ subSamples.size(), bytesDecryptedOut);
+}
+
+} // namespace clearkey
+} // namespace V1_1
+} // namespace drm
+} // namespace hardware
+} // namespace android
diff --git a/drm/mediadrm/plugins/clearkey/hidl/SessionLibrary.cpp b/drm/mediadrm/plugins/clearkey/hidl/SessionLibrary.cpp
new file mode 100644
index 0000000..b4319e6
--- /dev/null
+++ b/drm/mediadrm/plugins/clearkey/hidl/SessionLibrary.cpp
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2018 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.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "hidl_ClearKeySessionLibrary"
+#include <utils/Log.h>
+
+#include "SessionLibrary.h"
+#include "Utils.h"
+
+namespace android {
+namespace hardware {
+namespace drm {
+namespace V1_1 {
+namespace clearkey {
+
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::sp;
+
+Mutex SessionLibrary::sSingletonLock;
+SessionLibrary* SessionLibrary::sSingleton = NULL;
+
+SessionLibrary* SessionLibrary::get() {
+ Mutex::Autolock lock(sSingletonLock);
+
+ if (sSingleton == NULL) {
+ ALOGD("Instantiating Session Library Singleton.");
+ sSingleton = new SessionLibrary();
+ }
+
+ return sSingleton;
+}
+
+sp<Session> SessionLibrary::createSession() {
+ Mutex::Autolock lock(mSessionsLock);
+
+ char sessionIdRaw[16];
+ snprintf(sessionIdRaw, sizeof(sessionIdRaw), "%u", mNextSessionId);
+
+ mNextSessionId += 1;
+
+ std::vector<uint8_t> sessionId;
+ sessionId.insert(sessionId.end(), sessionIdRaw,
+ sessionIdRaw + sizeof(sessionIdRaw) / sizeof(uint8_t));
+
+ mSessions.insert(std::pair<std::vector<uint8_t>,
+ sp<Session> >(sessionId, new Session(sessionId)));
+ std::map<std::vector<uint8_t>, sp<Session> >::iterator itr = mSessions.find(sessionId);
+ if (itr != mSessions.end()) {
+ return itr->second;
+ } else {
+ return nullptr;
+ }
+}
+
+sp<Session> SessionLibrary::findSession(
+ const std::vector<uint8_t>& sessionId) {
+ Mutex::Autolock lock(mSessionsLock);
+ std::map<std::vector<uint8_t>, sp<Session> >::iterator itr = mSessions.find(sessionId);
+ if (itr != mSessions.end()) {
+ return itr->second;
+ } else {
+ return nullptr;
+ }
+}
+
+void SessionLibrary::destroySession(const sp<Session>& session) {
+ Mutex::Autolock lock(mSessionsLock);
+ mSessions.erase(session->sessionId());
+}
+
+} // namespace clearkey
+} // namespace V1_1
+} // namespace drm
+} // namespace hardware
+} // namespace android
diff --git a/drm/mediadrm/plugins/clearkey/hidl/android.hardware.drm@1.1-service.clearkey.rc b/drm/mediadrm/plugins/clearkey/hidl/android.hardware.drm@1.1-service.clearkey.rc
new file mode 100644
index 0000000..ffe856a
--- /dev/null
+++ b/drm/mediadrm/plugins/clearkey/hidl/android.hardware.drm@1.1-service.clearkey.rc
@@ -0,0 +1,6 @@
+service vendor.drm-clearkey-hal-1-1 /vendor/bin/hw/android.hardware.drm@1.1-service.clearkey
+ class hal
+ user media
+ group media mediadrm
+ ioprio rt 4
+ writepid /dev/cpuset/foreground/tasks
diff --git a/drm/mediadrm/plugins/clearkey/hidl/include/AesCtrDecryptor.h b/drm/mediadrm/plugins/clearkey/hidl/include/AesCtrDecryptor.h
new file mode 100644
index 0000000..0c7ef20
--- /dev/null
+++ b/drm/mediadrm/plugins/clearkey/hidl/include/AesCtrDecryptor.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2018 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 CLEARKEY_AES_CTR_DECRYPTOR_H_
+#define CLEARKEY_AES_CTR_DECRYPTOR_H_
+
+#include "ClearKeyTypes.h"
+
+namespace android {
+namespace hardware {
+namespace drm {
+namespace V1_1 {
+namespace clearkey {
+
+using ::android::hardware::drm::V1_0::Status;
+using ::android::hardware::drm::V1_0::SubSample;
+
+class AesCtrDecryptor {
+public:
+ AesCtrDecryptor() {}
+
+ Status decrypt(const std::vector<uint8_t>& key, const Iv iv,
+ const uint8_t* source, uint8_t* destination,
+ const std::vector<SubSample> subSamples, size_t numSubSamples,
+ size_t* bytesDecryptedOut);
+
+private:
+ CLEARKEY_DISALLOW_COPY_AND_ASSIGN(AesCtrDecryptor);
+};
+
+} // namespace clearkey
+} // namespace V1_1
+} // namespace drm
+} // namespace hardware
+} // namespace android
+
+#endif // CLEARKEY_AES_CTR_DECRYPTOR_H_
diff --git a/drm/mediadrm/plugins/clearkey/hidl/include/Base64.h b/drm/mediadrm/plugins/clearkey/hidl/include/Base64.h
new file mode 100644
index 0000000..4a385bd
--- /dev/null
+++ b/drm/mediadrm/plugins/clearkey/hidl/include/Base64.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2018 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 BASE_64_H_
+
+#define BASE_64_H_
+
+#include <android/hardware/drm/1.0/types.h>
+
+#include "Buffer.h"
+
+namespace android {
+namespace hardware {
+namespace drm {
+namespace V1_1 {
+namespace clearkey {
+
+using ::android::sp;
+
+struct Buffer;
+
+sp<Buffer> decodeBase64(const std::string &s);
+void encodeBase64(const void *data, size_t size, std::string *out);
+
+void encodeBase64Url(const void *data, size_t size, std::string *out);
+
+} // namespace clearkey
+} // namespace V1_1
+} // namespace drm
+} // namespace hardware
+} // namespace android
+
+#endif // BASE_64_H_
diff --git a/drm/mediadrm/plugins/clearkey/hidl/include/Buffer.h b/drm/mediadrm/plugins/clearkey/hidl/include/Buffer.h
new file mode 100644
index 0000000..5bbb28a
--- /dev/null
+++ b/drm/mediadrm/plugins/clearkey/hidl/include/Buffer.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2018 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 BUFFER_H_
+#define BUFFER_H_
+
+#include <android/hardware/drm/1.0/types.h>
+#include <utils/RefBase.h>
+
+#include "ClearKeyTypes.h"
+
+namespace android {
+namespace hardware {
+namespace drm {
+namespace V1_1 {
+namespace clearkey {
+
+using ::android::sp;
+
+struct Buffer : public RefBase {
+ explicit Buffer(size_t capacity);
+
+ uint8_t *base() { return reinterpret_cast<uint8_t *>(mData); }
+ uint8_t *data() { return reinterpret_cast<uint8_t *>(mData) + mRangeOffset; }
+ size_t capacity() const { return mCapacity; }
+ size_t size() const { return mRangeLength; }
+ size_t offset() const { return mRangeOffset; }
+
+protected:
+ virtual ~Buffer();
+
+private:
+ void *mData;
+ size_t mCapacity;
+ size_t mRangeOffset;
+ size_t mRangeLength;
+
+ bool mOwnsData;
+
+ CLEARKEY_DISALLOW_COPY_AND_ASSIGN(Buffer);
+};
+
+} // namespace clearkey
+} // namespace V1_1
+} // namespace drm
+} // namespace hardware
+} // namespace android
+
+#endif // BUFFER_H_
diff --git a/drm/mediadrm/plugins/clearkey/hidl/include/ClearKeyDrmProperties.h b/drm/mediadrm/plugins/clearkey/hidl/include/ClearKeyDrmProperties.h
new file mode 100644
index 0000000..7731b14
--- /dev/null
+++ b/drm/mediadrm/plugins/clearkey/hidl/include/ClearKeyDrmProperties.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2017 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 CLEARKEY_DRM_PROPERTIES_H_
+#define CLEARKEY_DRM_PROPERTIES_H_
+
+#include <string.h>
+
+namespace android {
+namespace hardware {
+namespace drm {
+namespace V1_1 {
+namespace clearkey {
+
+static const std::string kVendorKey("vendor");
+static const std::string kVendorValue("Google");
+static const std::string kVersionKey("version");
+static const std::string kVersionValue("1.0");
+static const std::string kPluginDescriptionKey("description");
+static const std::string kPluginDescriptionValue("ClearKey CDM");
+static const std::string kAlgorithmsKey("algorithms");
+static const std::string kAlgorithmsValue("");
+static const std::string kListenerTestSupportKey("listenerTestSupport");
+static const std::string kListenerTestSupportValue("true");
+
+static const std::string kDeviceIdKey("deviceId");
+static const uint8_t kTestDeviceIdData[] =
+ {0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7,
+ 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf};
+// TODO stub out metrics for nw
+static const std::string kMetricsKey("metrics");
+static const uint8_t kMetricsData[] = { 0 };
+
+} // namespace clearkey
+} // namespace V1_1
+} // namespace drm
+} // namespace hardware
+} // namespace android
+
+#endif // CLEARKEY_DRM_PROPERTIES_H_
+
diff --git a/drm/mediadrm/plugins/clearkey/hidl/include/ClearKeyTypes.h b/drm/mediadrm/plugins/clearkey/hidl/include/ClearKeyTypes.h
new file mode 100644
index 0000000..46cb5e4
--- /dev/null
+++ b/drm/mediadrm/plugins/clearkey/hidl/include/ClearKeyTypes.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2018 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 CLEARKEY_MACROS_H_
+#define CLEARKEY_MACROS_H_
+
+#include <android/hardware/drm/1.0/types.h>
+
+#include <map>
+
+namespace android {
+namespace hardware {
+namespace drm {
+namespace V1_1 {
+namespace clearkey {
+
+using ::android::hardware::drm::V1_0::KeyValue;
+using ::android::hardware::hidl_vec;
+
+const uint8_t kBlockSize = 16; //AES_BLOCK_SIZE;
+typedef uint8_t KeyId[kBlockSize];
+typedef uint8_t Iv[kBlockSize];
+
+typedef ::android::hardware::drm::V1_0::SubSample SubSample;
+typedef std::map<std::vector<uint8_t>, std::vector<uint8_t> > KeyMap;
+
+#define CLEARKEY_DISALLOW_COPY_AND_ASSIGN(TypeName) \
+ TypeName(const TypeName&) = delete; \
+ void operator=(const TypeName&) = delete;
+
+#define CLEARKEY_DISALLOW_COPY_AND_ASSIGN_AND_NEW(TypeName) \
+ TypeName() = delete; \
+ TypeName(const TypeName&) = delete; \
+ void operator=(const TypeName&) = delete;
+
+} // namespace clearkey
+} // namespace V1_1
+} // namespace drm
+} // namespace hardware
+} // namespace android
+
+#endif // CLEARKEY_MACROS_H_
diff --git a/drm/mediadrm/plugins/clearkey/hidl/include/CreatePluginFactories.h b/drm/mediadrm/plugins/clearkey/hidl/include/CreatePluginFactories.h
new file mode 100644
index 0000000..9952027
--- /dev/null
+++ b/drm/mediadrm/plugins/clearkey/hidl/include/CreatePluginFactories.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2018 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 CLEARKEY_CREATE_PLUGIN_FACTORIES_H_
+#define CLEARKEY_CREATE_PLUGIN_FACTORIES_H_
+
+#include <android/hardware/drm/1.1/ICryptoFactory.h>
+#include <android/hardware/drm/1.1/IDrmFactory.h>
+
+namespace android {
+namespace hardware {
+namespace drm {
+namespace V1_1 {
+namespace clearkey {
+
+using ::android::hardware::drm::V1_1::ICryptoFactory;
+using ::android::hardware::drm::V1_1::IDrmFactory;
+
+extern "C" {
+ IDrmFactory* createDrmFactory();
+ ICryptoFactory* createCryptoFactory();
+}
+
+} // namespace clearkey
+} // namespace V1_1
+} // namespace drm
+} // namespace hardware
+} // namespace android
+#endif // CLEARKEY_CREATE_PLUGIN_FACTORIES_H_
diff --git a/drm/mediadrm/plugins/clearkey/hidl/include/CryptoFactory.h b/drm/mediadrm/plugins/clearkey/hidl/include/CryptoFactory.h
new file mode 100644
index 0000000..175ab76
--- /dev/null
+++ b/drm/mediadrm/plugins/clearkey/hidl/include/CryptoFactory.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2018 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 CLEARKEY_CRYPTO_FACTORY_H_
+#define CLEARKEY_CRYPTO_FACTORY_H_
+
+#include <android/hardware/drm/1.0/ICryptoPlugin.h>
+#include <android/hardware/drm/1.1/ICryptoFactory.h>
+
+#include "ClearKeyTypes.h"
+
+namespace android {
+namespace hardware {
+namespace drm {
+namespace V1_1 {
+namespace clearkey {
+
+using ::android::hardware::drm::V1_1::ICryptoFactory;
+using ::android::hardware::drm::V1_0::ICryptoPlugin;
+using ::android::hardware::hidl_array;
+using ::android::hardware::hidl_string;
+using ::android::hardware::Return;
+
+struct CryptoFactory : public ICryptoFactory {
+ CryptoFactory() {}
+ virtual ~CryptoFactory() {}
+
+ 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:
+ CLEARKEY_DISALLOW_COPY_AND_ASSIGN(CryptoFactory);
+
+};
+
+} // namespace clearkey
+} // namespace V1_1
+} // namespace drm
+} // namespace hardware
+} // namespace android
+
+#endif // CLEARKEY_CRYPTO_FACTORY_H_
diff --git a/drm/mediadrm/plugins/clearkey/hidl/include/CryptoPlugin.h b/drm/mediadrm/plugins/clearkey/hidl/include/CryptoPlugin.h
new file mode 100644
index 0000000..6a73806
--- /dev/null
+++ b/drm/mediadrm/plugins/clearkey/hidl/include/CryptoPlugin.h
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2018 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 CLEARKEY_CRYPTO_PLUGIN_H_
+#define CLEARKEY_CRYPTO_PLUGIN_H_
+
+#include <android/hardware/drm/1.0/ICryptoPlugin.h>
+#include <android/hidl/memory/1.0/IMemory.h>
+
+#include "ClearKeyTypes.h"
+#include "Session.h"
+#include "Utils.h"
+
+namespace {
+ static const size_t KEY_ID_SIZE = 16;
+ static const size_t KEY_IV_SIZE = 16;
+}
+
+namespace android {
+namespace hardware {
+namespace drm {
+namespace V1_1 {
+namespace clearkey {
+
+using ::android::hardware::drm::V1_0::DestinationBuffer;
+using ::android::hardware::drm::V1_0::ICryptoPlugin;
+using ::android::hardware::drm::V1_0::Mode;
+using ::android::hardware::drm::V1_0::Pattern;
+using ::android::hardware::drm::V1_0::SharedBuffer;
+using ::android::hardware::drm::V1_0::Status;
+using ::android::hardware::drm::V1_0::SubSample;
+using ::android::hardware::hidl_array;
+using ::android::hardware::hidl_memory;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hidl::memory::V1_0::IMemory;
+using ::android::sp;
+
+struct CryptoPlugin : public ICryptoPlugin {
+ explicit CryptoPlugin(const hidl_vec<uint8_t>& sessionId) {
+ mInitStatus = setMediaDrmSession(sessionId);
+ }
+ virtual ~CryptoPlugin() {}
+
+ Return<bool> requiresSecureDecoderComponent(const hidl_string& mime) {
+ UNUSED(mime);
+ return false;
+ }
+
+ Return<void> notifyResolution(uint32_t width, uint32_t height) {
+ UNUSED(width);
+ UNUSED(height);
+ return Void();
+ }
+
+ Return<void> decrypt(
+ bool secure,
+ const hidl_array<uint8_t, KEY_ID_SIZE>& keyId,
+ const hidl_array<uint8_t, KEY_IV_SIZE>& iv,
+ Mode mode,
+ const Pattern& pattern,
+ const hidl_vec<SubSample>& subSamples,
+ const SharedBuffer& source,
+ uint64_t offset,
+ const DestinationBuffer& destination,
+ decrypt_cb _hidl_cb);
+
+ Return<void> setSharedBufferBase(const hidl_memory& base,
+ uint32_t bufferId);
+
+ Return<Status> setMediaDrmSession(const hidl_vec<uint8_t>& sessionId);
+
+ Return<Status> getInitStatus() const { return mInitStatus; }
+
+private:
+ CLEARKEY_DISALLOW_COPY_AND_ASSIGN(CryptoPlugin);
+
+ std::map<uint32_t, sp<IMemory> > mSharedBufferMap;
+ sp<Session> mSession;
+ Status mInitStatus;
+};
+
+} // namespace clearkey
+} // namespace V1_1
+} // namespace drm
+} // namespace hardware
+} // namespace android
+
+#endif // CLEARKEY_CRYPTO_PLUGIN_H_
diff --git a/drm/mediadrm/plugins/clearkey/hidl/include/DrmFactory.h b/drm/mediadrm/plugins/clearkey/hidl/include/DrmFactory.h
new file mode 100644
index 0000000..6f58195
--- /dev/null
+++ b/drm/mediadrm/plugins/clearkey/hidl/include/DrmFactory.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2018 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 CLEARKEY_DRM_FACTORY_H_
+#define CLEARKEY_DRM_FACTORY_H_
+
+#include <android/hardware/drm/1.1/IDrmPlugin.h>
+#include <android/hardware/drm/1.1/IDrmFactory.h>
+
+#include "ClearKeyTypes.h"
+
+namespace android {
+namespace hardware {
+namespace drm {
+namespace V1_1 {
+namespace clearkey {
+
+using ::android::hardware::hidl_array;
+using ::android::hardware::hidl_string;
+using ::android::hardware::Return;
+
+struct DrmFactory : public IDrmFactory {
+ DrmFactory() {}
+ virtual ~DrmFactory() {}
+
+ Return<bool> isCryptoSchemeSupported(const hidl_array<uint8_t, 16>& uuid)
+ override;
+
+ Return<bool> isContentTypeSupported(const hidl_string &mimeType)
+ override;
+
+ Return<void> createPlugin(
+ const hidl_array<uint8_t, 16>& uuid,
+ const hidl_string& appPackageName,
+ createPlugin_cb _hidl_cb) override;
+
+private:
+ CLEARKEY_DISALLOW_COPY_AND_ASSIGN(DrmFactory);
+};
+
+} // namespace clearkey
+} // namespace V1_1
+} // namespace drm
+} // namespace hardware
+} // namespace android
+
+#endif // CLEARKEY_DRM_FACTORY_H_
diff --git a/drm/mediadrm/plugins/clearkey/hidl/include/DrmPlugin.h b/drm/mediadrm/plugins/clearkey/hidl/include/DrmPlugin.h
new file mode 100644
index 0000000..5ae9833
--- /dev/null
+++ b/drm/mediadrm/plugins/clearkey/hidl/include/DrmPlugin.h
@@ -0,0 +1,353 @@
+/*
+ * Copyright (C) 2018 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 CLEARKEY_DRM_PLUGIN_H_
+#define CLEARKEY_DRM_PLUGIN_H_
+
+
+#include <android/hardware/drm/1.1/IDrmPlugin.h>
+
+#include "SessionLibrary.h"
+#include "Utils.h"
+
+namespace android {
+namespace hardware {
+namespace drm {
+namespace V1_1 {
+namespace clearkey {
+
+using ::android::hardware::drm::V1_0::EventType;
+using ::android::hardware::drm::V1_0::IDrmPluginListener;
+using ::android::hardware::drm::V1_0::KeyRequestType;
+using ::android::hardware::drm::V1_0::KeyStatus;
+using ::android::hardware::drm::V1_0::KeyType;
+using ::android::hardware::drm::V1_0::KeyValue;
+using ::android::hardware::drm::V1_0::SecureStop;
+using ::android::hardware::drm::V1_0::SecureStopId;
+using ::android::hardware::drm::V1_0::Status;
+
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::sp;
+
+struct DrmPlugin : public IDrmPlugin {
+ explicit DrmPlugin(SessionLibrary* sessionLibrary);
+
+ virtual ~DrmPlugin() {}
+
+ Return<void> openSession(openSession_cb _hidl_cb) override;
+
+ Return<Status> closeSession(const hidl_vec<uint8_t>& sessionId) override;
+
+ Return<void> getKeyRequest(
+ const hidl_vec<uint8_t>& scope,
+ const hidl_vec<uint8_t>& initData,
+ const hidl_string& mimeType,
+ KeyType keyType,
+ const hidl_vec<KeyValue>& optionalParameters,
+ getKeyRequest_cb _hidl_cb) override;
+
+ Return<void> getKeyRequest_1_1(
+ const hidl_vec<uint8_t>& scope,
+ const hidl_vec<uint8_t>& initData,
+ const hidl_string& mimeType,
+ KeyType keyType,
+ const hidl_vec<KeyValue>& optionalParameters,
+ getKeyRequest_1_1_cb _hidl_cb) override;
+
+ Return<void> provideKeyResponse(
+ const hidl_vec<uint8_t>& scope,
+ const hidl_vec<uint8_t>& response,
+ provideKeyResponse_cb _hidl_cb) override;
+
+ Return<Status> removeKeys(const hidl_vec<uint8_t>& sessionId) {
+ if (sessionId.size() == 0) {
+ return Status::BAD_VALUE;
+ }
+ return Status::ERROR_DRM_CANNOT_HANDLE;
+ }
+
+ Return<Status> restoreKeys(
+ const hidl_vec<uint8_t>& sessionId,
+ const hidl_vec<uint8_t>& keySetId) {
+
+ if (sessionId.size() == 0 || keySetId.size() == 0) {
+ return Status::BAD_VALUE;
+ }
+ return Status::ERROR_DRM_CANNOT_HANDLE;
+ }
+
+ Return<void> queryKeyStatus(
+ const hidl_vec<uint8_t>& sessionId,
+ queryKeyStatus_cb _hidl_cb) override;
+
+ Return<void> getProvisionRequest(
+ const hidl_string& certificateType,
+ const hidl_string& certificateAuthority,
+ getProvisionRequest_cb _hidl_cb) {
+ UNUSED(certificateType);
+ UNUSED(certificateAuthority);
+
+ hidl_string defaultUrl;
+ _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, hidl_vec<uint8_t>(), defaultUrl);
+ return Void();
+ }
+
+ Return<void> provideProvisionResponse(
+ const hidl_vec<uint8_t>& response,
+ provideProvisionResponse_cb _hidl_cb) {
+
+ if (response.size() == 0) {
+ _hidl_cb(Status::BAD_VALUE, hidl_vec<uint8_t>(), hidl_vec<uint8_t>());
+ return Void();
+ }
+ _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, hidl_vec<uint8_t>(), hidl_vec<uint8_t>());
+ return Void();
+ }
+
+ Return<void> getSecureStops(getSecureStops_cb _hidl_cb) {
+ _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, hidl_vec<SecureStop>());
+ return Void();
+ }
+
+ Return<void> getSecureStop(
+ const hidl_vec<uint8_t>& secureStopId,
+ getSecureStop_cb _hidl_cb) {
+
+ if (secureStopId.size() == 0) {
+ _hidl_cb(Status::BAD_VALUE, SecureStop());
+ return Void();
+ }
+ _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, SecureStop());
+ return Void();
+ }
+
+ Return<Status> releaseSecureStop(const hidl_vec<uint8_t>& ssRelease) {
+ if (ssRelease.size() == 0) {
+ return Status::BAD_VALUE;
+ }
+ return Status::ERROR_DRM_CANNOT_HANDLE;
+ }
+
+ Return<Status> releaseAllSecureStops() {
+ return Status::ERROR_DRM_CANNOT_HANDLE;
+ }
+
+ Return<void> getHdcpLevels(getHdcpLevels_cb _hidl_cb) {
+ HdcpLevel connectedLevel = HdcpLevel::HDCP_NONE;
+ HdcpLevel maxLevel = HdcpLevel::HDCP_NO_OUTPUT;
+ _hidl_cb(Status::OK, connectedLevel, maxLevel);
+ return Void();
+ }
+
+ Return<void> getNumberOfSessions(getNumberOfSessions_cb _hidl_cb) override;
+
+ Return<void> getSecurityLevel(const hidl_vec<uint8_t>& sessionId,
+ getSecurityLevel_cb _hidl_cb) override;
+
+ Return<Status> setSecurityLevel(const hidl_vec<uint8_t>& sessionId,
+ SecurityLevel level) override;
+
+ Return<void> getPropertyString(
+ const hidl_string& name,
+ getPropertyString_cb _hidl_cb) override;
+
+ Return<void> getPropertyByteArray(
+ const hidl_string& name,
+ getPropertyByteArray_cb _hidl_cb) override;
+
+ Return<Status> setPropertyString(
+ const hidl_string& name, const hidl_string& value) override;
+
+ Return<Status> setPropertyByteArray(
+ const hidl_string& name, const hidl_vec<uint8_t>& value) override;
+
+ Return<Status> setCipherAlgorithm(
+ const hidl_vec<uint8_t>& sessionId, const hidl_string& algorithm) {
+ if (sessionId.size() == 0 || algorithm.size() == 0) {
+ return Status::BAD_VALUE;
+ }
+ return Status::ERROR_DRM_CANNOT_HANDLE;
+ }
+
+ Return<Status> setMacAlgorithm(
+ const hidl_vec<uint8_t>& sessionId, const hidl_string& algorithm) {
+ if (sessionId.size() == 0 || algorithm.size() == 0) {
+ return Status::BAD_VALUE;
+ }
+ return Status::ERROR_DRM_CANNOT_HANDLE;
+ }
+
+ Return<void> encrypt(
+ const hidl_vec<uint8_t>& sessionId,
+ const hidl_vec<uint8_t>& keyId,
+ const hidl_vec<uint8_t>& input,
+ const hidl_vec<uint8_t>& iv,
+ encrypt_cb _hidl_cb) {
+ if (sessionId.size() == 0 || keyId.size() == 0 ||
+ input.size() == 0 || iv.size() == 0) {
+ _hidl_cb(Status::BAD_VALUE, hidl_vec<uint8_t>());
+ return Void();
+ }
+ _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, hidl_vec<uint8_t>());
+ return Void();
+ }
+
+ Return<void> decrypt(
+ const hidl_vec<uint8_t>& sessionId,
+ const hidl_vec<uint8_t>& keyId,
+ const hidl_vec<uint8_t>& input,
+ const hidl_vec<uint8_t>& iv,
+ decrypt_cb _hidl_cb) {
+ if (sessionId.size() == 0 || keyId.size() == 0 ||
+ input.size() == 0 || iv.size() == 0) {
+ _hidl_cb(Status::BAD_VALUE, hidl_vec<uint8_t>());
+ return Void();
+ }
+ _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, hidl_vec<uint8_t>());
+ return Void();
+ }
+
+ Return<void> sign(
+ const hidl_vec<uint8_t>& sessionId,
+ const hidl_vec<uint8_t>& keyId,
+ const hidl_vec<uint8_t>& message,
+ sign_cb _hidl_cb) {
+ if (sessionId.size() == 0 || keyId.size() == 0 ||
+ message.size() == 0) {
+ _hidl_cb(Status::BAD_VALUE, hidl_vec<uint8_t>());
+ return Void();
+ }
+ _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, hidl_vec<uint8_t>());
+ return Void();
+ }
+
+ Return<void> verify(
+ const hidl_vec<uint8_t>& sessionId,
+ const hidl_vec<uint8_t>& keyId,
+ const hidl_vec<uint8_t>& message,
+ const hidl_vec<uint8_t>& signature,
+ verify_cb _hidl_cb) {
+
+ if (sessionId.size() == 0 || keyId.size() == 0 ||
+ message.size() == 0 || signature.size() == 0) {
+ _hidl_cb(Status::BAD_VALUE, false);
+ return Void();
+ }
+ _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, false);
+ return Void();
+ }
+
+ Return<void> signRSA(
+ const hidl_vec<uint8_t>& sessionId,
+ const hidl_string& algorithm,
+ const hidl_vec<uint8_t>& message,
+ const hidl_vec<uint8_t>& wrappedKey,
+ signRSA_cb _hidl_cb) {
+ if (sessionId.size() == 0 || algorithm.size() == 0 ||
+ message.size() == 0 || wrappedKey.size() == 0) {
+ _hidl_cb(Status::BAD_VALUE, hidl_vec<uint8_t>());
+ return Void();
+ }
+ _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, hidl_vec<uint8_t>());
+ return Void();
+ }
+
+ Return<void> setListener(const sp<IDrmPluginListener>& listener) {
+ mListener = listener;
+ return Void();
+ };
+
+ Return<void> sendEvent(EventType eventType, const hidl_vec<uint8_t>& sessionId,
+ const hidl_vec<uint8_t>& data) {
+ if (mListener != NULL) {
+ mListener->sendEvent(eventType, sessionId, data);
+ } else {
+ ALOGE("Null event listener, event not sent");
+ }
+ return Void();
+ }
+
+ Return<void> sendExpirationUpdate(const hidl_vec<uint8_t>& sessionId, int64_t expiryTimeInMS) {
+ if (mListener != NULL) {
+ mListener->sendExpirationUpdate(sessionId, expiryTimeInMS);
+ } else {
+ ALOGE("Null event listener, event not sent");
+ }
+ return Void();
+ }
+
+ Return<void> sendKeysChange(const hidl_vec<uint8_t>& sessionId,
+ const hidl_vec<KeyStatus>& keyStatusList, bool hasNewUsableKey) {
+ if (mListener != NULL) {
+ mListener->sendKeysChange(sessionId, keyStatusList, hasNewUsableKey);
+ } else {
+ ALOGE("Null event listener, event not sent");
+ }
+ return Void();
+ }
+
+ Return<void> getMetrics(getMetrics_cb _hidl_cb) {
+ _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, hidl_vec<DrmMetricGroup>());
+ return Void();
+ }
+
+ Return<void> getSecureStopIds(getSecureStopIds_cb _hidl_cb) {
+ _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, hidl_vec<SecureStopId>());
+ return Void();
+ }
+
+ Return<Status> releaseSecureStops(const SecureStopRelease& ssRelease) {
+ if (ssRelease.opaqueData.size() == 0) {
+ return Status::BAD_VALUE;
+ }
+ return Status::ERROR_DRM_CANNOT_HANDLE;
+ }
+
+ Return<Status> removeSecureStop(const hidl_vec<uint8_t>& secureStopId) {
+ if (secureStopId.size() == 0) {
+ return Status::BAD_VALUE;
+ }
+ return Status::ERROR_DRM_CANNOT_HANDLE;
+ }
+
+ Return<Status> removeAllSecureStops() {
+ return Status::ERROR_DRM_CANNOT_HANDLE;
+ }
+
+private:
+ void initProperties();
+ void setPlayPolicy();
+
+ std::vector<KeyValue> mPlayPolicy;
+ std::map<std::string, std::string> mStringProperties;
+ std::map<std::string, std::vector<uint8_t> > mByteArrayProperties;
+ std::map<std::vector<uint8_t>, SecurityLevel> mSecurityLevel;
+ sp<IDrmPluginListener> mListener;
+ SessionLibrary *mSessionLibrary;
+
+ CLEARKEY_DISALLOW_COPY_AND_ASSIGN_AND_NEW(DrmPlugin);
+};
+
+} // namespace clearkey
+} // namespace V1_1
+} // namespace drm
+} // namespace hardware
+} // namespace android
+
+#endif // CLEARKEY_DRM_PLUGIN_H_
diff --git a/drm/mediadrm/plugins/clearkey/hidl/include/InitDataParser.h b/drm/mediadrm/plugins/clearkey/hidl/include/InitDataParser.h
new file mode 100644
index 0000000..3189c4a
--- /dev/null
+++ b/drm/mediadrm/plugins/clearkey/hidl/include/InitDataParser.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2018 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 CLEARKEY_INIT_DATA_PARSER_H_
+#define CLEARKEY_INIT_DATA_PARSER_H_
+
+#include <android/hardware/drm/1.0/types.h>
+
+#include "ClearKeyTypes.h"
+
+namespace android {
+namespace hardware {
+namespace drm {
+namespace V1_1 {
+namespace clearkey {
+
+using ::android::hardware::drm::V1_0::Status;
+
+class InitDataParser {
+public:
+ InitDataParser() {}
+
+ Status parse(const std::vector<uint8_t>& initData,
+ const std::string& type,
+ std::vector<uint8_t>* licenseRequest);
+
+private:
+ CLEARKEY_DISALLOW_COPY_AND_ASSIGN(InitDataParser);
+
+ Status parsePssh(const std::vector<uint8_t>& initData,
+ std::vector<const uint8_t*>* keyIds);
+
+ std::string generateRequest(
+ const std::vector<const uint8_t*>& keyIds);
+};
+
+} // namespace clearkey
+} // namespace V1_1
+} // namespace drm
+} // namespace hardware
+} // namespace android
+
+#endif // CLEARKEY_INIT_DATA_PARSER_H_
diff --git a/drm/mediadrm/plugins/clearkey/hidl/include/JsonWebKey.h b/drm/mediadrm/plugins/clearkey/hidl/include/JsonWebKey.h
new file mode 100644
index 0000000..4ab034c
--- /dev/null
+++ b/drm/mediadrm/plugins/clearkey/hidl/include/JsonWebKey.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2018 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 CLEARKEY_JSON_WEB_KEY_H_
+#define CLEARKEY_JSON_WEB_KEY_H_
+
+#include "jsmn.h"
+#include "Utils.h"
+#include "ClearKeyTypes.h"
+
+namespace android {
+namespace hardware {
+namespace drm {
+namespace V1_1 {
+namespace clearkey {
+
+class JsonWebKey {
+ public:
+ JsonWebKey();
+ virtual ~JsonWebKey();
+
+ bool extractKeysFromJsonWebKeySet(const std::string& jsonWebKeySet,
+ KeyMap* keys);
+
+ private:
+ std::vector<jsmntok_t> mJsmnTokens;
+ std::vector<std::string> mJsonObjects;
+ std::vector<std::string> mTokens;
+
+ bool decodeBase64String(const std::string& encodedText,
+ std::vector<uint8_t>* decodedText);
+ bool findKey(const std::string& jsonObject, std::string* keyId,
+ std::string* encodedKey);
+ void findValue(const std::string &key, std::string* value);
+ bool isJsonWebKeySet(const std::string& jsonObject) const;
+ bool parseJsonObject(const std::string& jsonObject,
+ std::vector<std::string>* tokens);
+ bool parseJsonWebKeySet(const std::string& jsonWebKeySet,
+ std::vector<std::string>* jsonObjects);
+
+ CLEARKEY_DISALLOW_COPY_AND_ASSIGN(JsonWebKey);
+};
+
+} // namespace clearkey
+} // namespace V1_1
+} // namespace drm
+} // namespace hardware
+} // namespace android
+
+#endif // CLEARKEY_JSON_WEB_KEY_H_
diff --git a/drm/mediadrm/plugins/clearkey/hidl/include/Session.h b/drm/mediadrm/plugins/clearkey/hidl/include/Session.h
new file mode 100644
index 0000000..cddfca5
--- /dev/null
+++ b/drm/mediadrm/plugins/clearkey/hidl/include/Session.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2018 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 CLEARKEY_SESSION_H_
+#define CLEARKEY_SESSION_H_
+
+#include <utils/Mutex.h>
+#include <utils/RefBase.h>
+#include <vector>
+
+#include "ClearKeyTypes.h"
+
+
+namespace android {
+namespace hardware {
+namespace drm {
+namespace V1_1 {
+namespace clearkey {
+
+using ::android::hardware::drm::V1_0::Status;
+using ::android::hardware::drm::V1_0::SubSample;
+
+class Session : public RefBase {
+public:
+ explicit Session(const std::vector<uint8_t>& sessionId)
+ : mSessionId(sessionId) {}
+ virtual ~Session() {}
+
+ const std::vector<uint8_t>& sessionId() const { return mSessionId; }
+
+ Status getKeyRequest(
+ const std::vector<uint8_t>& mimeType,
+ const std::string& initDataType,
+ std::vector<uint8_t>* keyRequest) const;
+
+ Status provideKeyResponse(
+ const std::vector<uint8_t>& response);
+
+ Status decrypt(
+ const KeyId keyId, const Iv iv, const uint8_t* srcPtr,
+ uint8_t* dstPtr, const std::vector<SubSample> subSamples,
+ size_t* bytesDecryptedOut);
+
+private:
+ CLEARKEY_DISALLOW_COPY_AND_ASSIGN(Session);
+
+ const std::vector<uint8_t> mSessionId;
+ KeyMap mKeyMap;
+ Mutex mMapLock;
+};
+
+} // namespace clearkey
+} // namespace V1_1
+} // namespace drm
+} // namespace hardware
+} // namespace android
+
+#endif // CLEARKEY_SESSION_H_
diff --git a/drm/mediadrm/plugins/clearkey/hidl/include/SessionLibrary.h b/drm/mediadrm/plugins/clearkey/hidl/include/SessionLibrary.h
new file mode 100644
index 0000000..326a0c1
--- /dev/null
+++ b/drm/mediadrm/plugins/clearkey/hidl/include/SessionLibrary.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2018 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 CLEARKEY_SESSION_LIBRARY_H_
+#define CLEARKEY_SESSION_LIBRARY_H_
+
+#include <utils/RefBase.h>
+#include <utils/Mutex.h>
+
+#include "ClearKeyTypes.h"
+#include "Session.h"
+
+namespace android {
+namespace hardware {
+namespace drm {
+namespace V1_1 {
+namespace clearkey {
+
+using ::android::sp;
+
+class SessionLibrary : public RefBase {
+public:
+ static SessionLibrary* get();
+
+ sp<Session> createSession();
+
+ sp<Session> findSession(
+ const std::vector<uint8_t>& sessionId);
+
+ void destroySession(const sp<Session>& session);
+
+ size_t numOpenSessions() const { return mSessions.size(); }
+
+private:
+ CLEARKEY_DISALLOW_COPY_AND_ASSIGN(SessionLibrary);
+
+ SessionLibrary() : mNextSessionId(1) {}
+
+ static Mutex sSingletonLock;
+ static SessionLibrary* sSingleton;
+
+ Mutex mSessionsLock;
+ uint32_t mNextSessionId;
+ std::map<std::vector<uint8_t>, sp<Session> > mSessions;
+};
+
+} // namespace clearkey
+} // namespace V1_1
+} // namespace drm
+} // namespace hardware
+} // namespace android
+
+#endif // CLEARKEY_SESSION_LIBRARY_H_
diff --git a/drm/mediadrm/plugins/clearkey/hidl/include/TypeConvert.h b/drm/mediadrm/plugins/clearkey/hidl/include/TypeConvert.h
new file mode 100644
index 0000000..cc06329
--- /dev/null
+++ b/drm/mediadrm/plugins/clearkey/hidl/include/TypeConvert.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2018 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 CLEARKEY_ANDROID_HARDWARE_DRM_V1_1_TYPECONVERT
+#define CLEARKEY_ANDROID_HARDWARE_DRM_V1_1_TYPECONVERT
+
+#include <vector>
+
+#include <android/hardware/drm/1.0/types.h>
+
+namespace android {
+namespace hardware {
+namespace drm {
+namespace V1_1 {
+namespace clearkey {
+
+using ::android::hardware::hidl_array;
+using ::android::hardware::hidl_vec;
+
+template<typename T> const hidl_vec<T> toHidlVec(const std::vector<T> &vec) {
+ hidl_vec<T> hVec;
+ hVec.setToExternal(const_cast<T *>(vec.data()), vec.size());
+ return hVec;
+}
+
+template<typename T> hidl_vec<T> toHidlVec(std::vector<T> &vec) {
+ hidl_vec<T> hVec;
+ hVec.setToExternal(vec.data(), vec.size());
+ return hVec;
+}
+
+template<typename T> const std::vector<T> toVector(const hidl_vec<T> &hVec) {
+ std::vector<T> vec;
+ vec.assign(hVec.data(), hVec.data() + hVec.size());
+ return *const_cast<const std::vector<T> *>(&vec);
+}
+
+template<typename T> std::vector<T> toVector(hidl_vec<T> &hVec) {
+ std::vector<T> vec;
+ vec.assign(hVec.data(), hVec.data() + hVec.size());
+ return vec;
+}
+
+template<typename T, size_t SIZE> const std::vector<T> toVector(
+ const hidl_array<T, SIZE> &hArray) {
+ std::vector<T> vec;
+ vec.assign(hArray.data(), hArray.data() + hArray.size());
+ return vec;
+}
+
+template<typename T, size_t SIZE> std::vector<T> toVector(
+ hidl_array<T, SIZE> &hArray) {
+ std::vector<T> vec;
+ vec.assign(hArray.data(), hArray.data() + hArray.size());
+ return vec;
+}
+
+} // namespace clearkey
+} // namespace V1_1
+} // namespace drm
+} // namespace hardware
+} // namespace android
+
+#endif // CLEARKEY_ANDROID_HARDWARE_DRM_V1_1_TYPECONVERT
diff --git a/drm/mediadrm/plugins/clearkey/hidl/service.cpp b/drm/mediadrm/plugins/clearkey/hidl/service.cpp
new file mode 100644
index 0000000..6a97b72
--- /dev/null
+++ b/drm/mediadrm/plugins/clearkey/hidl/service.cpp
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2018 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.
+ */
+#define LOG_TAG "android.hardware.drm@1.1-service.clearkey"
+
+#include <CryptoFactory.h>
+#include <DrmFactory.h>
+
+#include <android-base/logging.h>
+#include <binder/ProcessState.h>
+#include <hidl/HidlTransportSupport.h>
+
+using ::android::hardware::configureRpcThreadpool;
+using ::android::hardware::joinRpcThreadpool;
+using ::android::sp;
+
+using android::hardware::drm::V1_1::ICryptoFactory;
+using android::hardware::drm::V1_1::IDrmFactory;
+using android::hardware::drm::V1_1::clearkey::CryptoFactory;
+using android::hardware::drm::V1_1::clearkey::DrmFactory;
+
+
+int main(int /* argc */, char** /* argv */) {
+ ALOGD("android.hardware.drm@1.1-service.clearkey starting...");
+
+ // The DRM HAL may communicate to other vendor components via
+ // /dev/vndbinder
+ android::ProcessState::initWithDriver("/dev/vndbinder");
+
+ sp<IDrmFactory> drmFactory = new DrmFactory;
+ sp<ICryptoFactory> cryptoFactory = new CryptoFactory;
+
+ configureRpcThreadpool(8, true /* callerWillJoin */);
+
+ // Setup hwbinder service
+ CHECK_EQ(drmFactory->registerAsService("clearkey"), android::NO_ERROR)
+ << "Failed to register Clearkey Factory HAL";
+ CHECK_EQ(cryptoFactory->registerAsService("clearkey"), android::NO_ERROR)
+ << "Failed to register Clearkey Crypto HAL";
+
+ joinRpcThreadpool();
+}
diff --git a/include/media/DataSourceBase.h b/include/media/DataSourceBase.h
new file mode 120000
index 0000000..54c8047
--- /dev/null
+++ b/include/media/DataSourceBase.h
@@ -0,0 +1 @@
+../../media/libmediaextractor/include/media/DataSourceBase.h
\ No newline at end of file
diff --git a/media/extractors/aac/AACExtractor.cpp b/media/extractors/aac/AACExtractor.cpp
index 6f28374..1614ca4 100644
--- a/media/extractors/aac/AACExtractor.cpp
+++ b/media/extractors/aac/AACExtractor.cpp
@@ -19,7 +19,7 @@
#include <utils/Log.h>
#include "AACExtractor.h"
-#include <media/DataSource.h>
+#include <media/DataSourceBase.h>
#include <media/MediaSourceBase.h>
#include <media/stagefright/foundation/ABuffer.h>
#include <media/stagefright/foundation/AMessage.h>
@@ -35,7 +35,7 @@
class AACSource : public MediaSourceBase {
public:
- AACSource(const sp<DataSource> &source,
+ AACSource(DataSourceBase *source,
const sp<MetaData> &meta,
const Vector<uint64_t> &offset_vector,
int64_t frame_duration_us);
@@ -53,7 +53,7 @@
private:
static const size_t kMaxFrameSize;
- sp<DataSource> mDataSource;
+ DataSourceBase *mDataSource;
sp<MetaData> mMeta;
off64_t mOffset;
@@ -91,7 +91,7 @@
// The returned value is the AAC frame size with the ADTS header length (regardless of
// the presence of the CRC).
// If headerSize is non-NULL, it will be used to return the size of the header of this ADTS frame.
-static size_t getAdtsFrameLength(const sp<DataSource> &source, off64_t offset, size_t* headerSize) {
+static size_t getAdtsFrameLength(DataSourceBase *source, off64_t offset, size_t* headerSize) {
const size_t kAdtsHeaderLengthNoCrc = 7;
const size_t kAdtsHeaderLengthWithCrc = 9;
@@ -132,7 +132,7 @@
}
AACExtractor::AACExtractor(
- const sp<DataSource> &source, const sp<AMessage> &_meta)
+ DataSourceBase *source, const sp<AMessage> &_meta)
: mDataSource(source),
mInitCheck(NO_INIT),
mFrameDurationUs(0) {
@@ -229,7 +229,7 @@
const size_t AACSource::kMaxFrameSize = 8192;
AACSource::AACSource(
- const sp<DataSource> &source, const sp<MetaData> &meta,
+ DataSourceBase *source, const sp<MetaData> &meta,
const Vector<uint64_t> &offset_vector,
int64_t frame_duration_us)
: mDataSource(source),
@@ -332,13 +332,13 @@
////////////////////////////////////////////////////////////////////////////////
static MediaExtractor* CreateExtractor(
- const sp<DataSource> &source,
+ DataSourceBase *source,
const sp<AMessage>& meta) {
return new AACExtractor(source, meta);
}
static MediaExtractor::CreatorFunc Sniff(
- const sp<DataSource> &source, String8 *mimeType, float *confidence,
+ DataSourceBase *source, String8 *mimeType, float *confidence,
sp<AMessage> *meta) {
off64_t pos = 0;
diff --git a/media/extractors/aac/AACExtractor.h b/media/extractors/aac/AACExtractor.h
index 33fbba7..e99699c 100644
--- a/media/extractors/aac/AACExtractor.h
+++ b/media/extractors/aac/AACExtractor.h
@@ -29,7 +29,7 @@
class AACExtractor : public MediaExtractor {
public:
- AACExtractor(const sp<DataSource> &source, const sp<AMessage> &meta);
+ AACExtractor(DataSourceBase *source, const sp<AMessage> &meta);
virtual size_t countTracks();
virtual MediaSourceBase *getTrack(size_t index);
@@ -42,7 +42,7 @@
virtual ~AACExtractor();
private:
- sp<DataSource> mDataSource;
+ DataSourceBase *mDataSource;
sp<MetaData> mMeta;
status_t mInitCheck;
@@ -54,7 +54,7 @@
};
bool SniffAAC(
- const sp<DataSource> &source, String8 *mimeType, float *confidence,
+ DataSourceBase *source, String8 *mimeType, float *confidence,
sp<AMessage> *);
} // namespace android
diff --git a/media/extractors/amr/AMRExtractor.cpp b/media/extractors/amr/AMRExtractor.cpp
index 10be50c..547e3f5 100644
--- a/media/extractors/amr/AMRExtractor.cpp
+++ b/media/extractors/amr/AMRExtractor.cpp
@@ -20,7 +20,7 @@
#include "AMRExtractor.h"
-#include <media/DataSource.h>
+#include <media/DataSourceBase.h>
#include <media/MediaSourceBase.h>
#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/MediaBufferGroup.h>
@@ -33,7 +33,7 @@
class AMRSource : public MediaSourceBase {
public:
- AMRSource(const sp<DataSource> &source,
+ AMRSource(DataSourceBase *source,
const sp<MetaData> &meta,
bool isWide,
const off64_t *offset_table,
@@ -51,7 +51,7 @@
virtual ~AMRSource();
private:
- sp<DataSource> mDataSource;
+ DataSourceBase *mDataSource;
sp<MetaData> mMeta;
bool mIsWide;
@@ -97,7 +97,7 @@
return frameSize;
}
-static status_t getFrameSizeByOffset(const sp<DataSource> &source,
+static status_t getFrameSizeByOffset(DataSourceBase *source,
off64_t offset, bool isWide, size_t *frameSize) {
uint8_t header;
ssize_t count = source->readAt(offset, &header, 1);
@@ -116,7 +116,7 @@
return OK;
}
-AMRExtractor::AMRExtractor(const sp<DataSource> &source)
+AMRExtractor::AMRExtractor(DataSourceBase *source)
: mDataSource(source),
mInitCheck(NO_INIT),
mOffsetTableLength(0) {
@@ -206,7 +206,7 @@
////////////////////////////////////////////////////////////////////////////////
AMRSource::AMRSource(
- const sp<DataSource> &source, const sp<MetaData> &meta,
+ DataSourceBase *source, const sp<MetaData> &meta,
bool isWide, const off64_t *offset_table, size_t offset_table_length)
: mDataSource(source),
mMeta(meta),
@@ -339,7 +339,7 @@
////////////////////////////////////////////////////////////////////////////////
bool SniffAMR(
- const sp<DataSource> &source, String8 *mimeType, float *confidence,
+ DataSourceBase *source, String8 *mimeType, float *confidence,
sp<AMessage> *) {
char header[9];
@@ -372,13 +372,13 @@
1,
"AMR Extractor",
[](
- const sp<DataSource> &source,
+ DataSourceBase *source,
String8 *mimeType,
float *confidence,
sp<AMessage> *meta __unused) -> MediaExtractor::CreatorFunc {
if (SniffAMR(source, mimeType, confidence, meta)) {
return [](
- const sp<DataSource> &source,
+ DataSourceBase *source,
const sp<AMessage>& meta __unused) -> MediaExtractor* {
return new AMRExtractor(source);};
}
diff --git a/media/extractors/amr/AMRExtractor.h b/media/extractors/amr/AMRExtractor.h
index 56883e3..d6d49f2 100644
--- a/media/extractors/amr/AMRExtractor.h
+++ b/media/extractors/amr/AMRExtractor.h
@@ -29,7 +29,7 @@
class AMRExtractor : public MediaExtractor {
public:
- explicit AMRExtractor(const sp<DataSource> &source);
+ explicit AMRExtractor(DataSourceBase *source);
virtual size_t countTracks();
virtual MediaSourceBase *getTrack(size_t index);
@@ -42,7 +42,7 @@
virtual ~AMRExtractor();
private:
- sp<DataSource> mDataSource;
+ DataSourceBase *mDataSource;
sp<MetaData> mMeta;
status_t mInitCheck;
bool mIsWide;
@@ -55,7 +55,7 @@
};
bool SniffAMR(
- const sp<DataSource> &source, String8 *mimeType, float *confidence,
+ DataSourceBase *source, String8 *mimeType, float *confidence,
sp<AMessage> *);
} // namespace android
diff --git a/media/extractors/flac/FLACExtractor.cpp b/media/extractors/flac/FLACExtractor.cpp
index ba28e86..8dbb5a1 100644
--- a/media/extractors/flac/FLACExtractor.cpp
+++ b/media/extractors/flac/FLACExtractor.cpp
@@ -22,7 +22,7 @@
// libFLAC parser
#include "FLAC/stream_decoder.h"
-#include <media/DataSource.h>
+#include <media/DataSourceBase.h>
#include <media/MediaSourceBase.h>
#include <media/stagefright/foundation/ABuffer.h>
#include <media/stagefright/foundation/ADebug.h>
@@ -165,7 +165,7 @@
public:
FLACSource(
- const sp<DataSource> &dataSource,
+ DataSourceBase *dataSource,
const sp<MetaData> &trackMetadata);
virtual status_t start(MetaData *params);
@@ -179,7 +179,7 @@
virtual ~FLACSource();
private:
- sp<DataSource> mDataSource;
+ DataSourceBase *mDataSource;
sp<MetaData> mTrackMetadata;
sp<FLACParser> mParser;
bool mInitCheck;
@@ -203,7 +203,7 @@
};
explicit FLACParser(
- const sp<DataSource> &dataSource,
+ DataSourceBase *dataSource,
// If metadata pointers aren't provided, we don't fill them
const sp<MetaData> &fileMetadata = 0,
const sp<MetaData> &trackMetadata = 0);
@@ -243,7 +243,7 @@
virtual ~FLACParser();
private:
- sp<DataSource> mDataSource;
+ DataSourceBase *mDataSource;
sp<MetaData> mFileMetadata;
sp<MetaData> mTrackMetadata;
bool mInitCheck;
@@ -612,7 +612,7 @@
// FLACParser
FLACParser::FLACParser(
- const sp<DataSource> &dataSource,
+ DataSourceBase *dataSource,
const sp<MetaData> &fileMetadata,
const sp<MetaData> &trackMetadata)
: mDataSource(dataSource),
@@ -833,7 +833,7 @@
// FLACsource
FLACSource::FLACSource(
- const sp<DataSource> &dataSource,
+ DataSourceBase *dataSource,
const sp<MetaData> &trackMetadata)
: mDataSource(dataSource),
mTrackMetadata(trackMetadata),
@@ -918,7 +918,7 @@
// FLACExtractor
FLACExtractor::FLACExtractor(
- const sp<DataSource> &dataSource)
+ DataSourceBase *dataSource)
: mDataSource(dataSource),
mInitCheck(false)
{
@@ -969,7 +969,7 @@
// Sniffer
bool SniffFLAC(
- const sp<DataSource> &source, String8 *mimeType, float *confidence,
+ DataSourceBase *source, String8 *mimeType, float *confidence,
sp<AMessage> *)
{
// first 4 is the signature word
@@ -1000,13 +1000,13 @@
1,
"FLAC Extractor",
[](
- const sp<DataSource> &source,
+ DataSourceBase *source,
String8 *mimeType,
float *confidence,
sp<AMessage> *meta __unused) -> MediaExtractor::CreatorFunc {
if (SniffFLAC(source, mimeType, confidence, meta)) {
return [](
- const sp<DataSource> &source,
+ DataSourceBase *source,
const sp<AMessage>& meta __unused) -> MediaExtractor* {
return new FLACExtractor(source);};
}
diff --git a/media/extractors/flac/FLACExtractor.h b/media/extractors/flac/FLACExtractor.h
index 2e7ee3b..ef07212 100644
--- a/media/extractors/flac/FLACExtractor.h
+++ b/media/extractors/flac/FLACExtractor.h
@@ -17,7 +17,7 @@
#ifndef FLAC_EXTRACTOR_H_
#define FLAC_EXTRACTOR_H_
-#include <media/DataSource.h>
+#include <media/DataSourceBase.h>
#include <media/MediaExtractor.h>
#include <utils/String8.h>
@@ -28,8 +28,7 @@
class FLACExtractor : public MediaExtractor {
public:
- // Extractor assumes ownership of source
- explicit FLACExtractor(const sp<DataSource> &source);
+ explicit FLACExtractor(DataSourceBase *source);
virtual size_t countTracks();
virtual MediaSourceBase *getTrack(size_t index);
@@ -42,7 +41,7 @@
virtual ~FLACExtractor();
private:
- sp<DataSource> mDataSource;
+ DataSourceBase *mDataSource;
sp<FLACParser> mParser;
status_t mInitCheck;
sp<MetaData> mFileMetadata;
@@ -57,7 +56,7 @@
};
-bool SniffFLAC(const sp<DataSource> &source, String8 *mimeType,
+bool SniffFLAC(DataSourceBase *source, String8 *mimeType,
float *confidence, sp<AMessage> *);
} // namespace android
diff --git a/media/extractors/midi/MidiExtractor.cpp b/media/extractors/midi/MidiExtractor.cpp
index 18b1d23..711c6a5 100644
--- a/media/extractors/midi/MidiExtractor.cpp
+++ b/media/extractors/midi/MidiExtractor.cpp
@@ -141,7 +141,7 @@
// MidiEngine
-MidiEngine::MidiEngine(const sp<DataSource> &dataSource,
+MidiEngine::MidiEngine(DataSourceBase *dataSource,
const sp<MetaData> &fileMetadata,
const sp<MetaData> &trackMetadata) :
mGroup(NULL),
@@ -261,7 +261,7 @@
// MidiExtractor
MidiExtractor::MidiExtractor(
- const sp<DataSource> &dataSource)
+ DataSourceBase *dataSource)
: mDataSource(dataSource),
mInitCheck(false)
{
@@ -308,7 +308,7 @@
// Sniffer
bool SniffMidi(
- const sp<DataSource> &source, String8 *mimeType, float *confidence,
+ DataSourceBase *source, String8 *mimeType, float *confidence,
sp<AMessage> *)
{
sp<MidiEngine> p = new MidiEngine(source, NULL, NULL);
@@ -333,13 +333,13 @@
1,
"MIDI Extractor",
[](
- const sp<DataSource> &source,
+ DataSourceBase *source,
String8 *mimeType,
float *confidence,
sp<AMessage> *meta __unused) -> MediaExtractor::CreatorFunc {
if (SniffMidi(source, mimeType, confidence, meta)) {
return [](
- const sp<DataSource> &source,
+ DataSourceBase *source,
const sp<AMessage>& meta __unused) -> MediaExtractor* {
return new MidiExtractor(source);};
}
diff --git a/media/extractors/midi/MidiExtractor.h b/media/extractors/midi/MidiExtractor.h
index 87e4654..91efd06 100644
--- a/media/extractors/midi/MidiExtractor.h
+++ b/media/extractors/midi/MidiExtractor.h
@@ -17,7 +17,7 @@
#ifndef MIDI_EXTRACTOR_H_
#define MIDI_EXTRACTOR_H_
-#include <media/DataSource.h>
+#include <media/DataSourceBase.h>
#include <media/MediaExtractor.h>
#include <media/stagefright/MediaBuffer.h>
#include <media/stagefright/MediaBufferGroup.h>
@@ -29,7 +29,7 @@
class MidiEngine : public RefBase {
public:
- MidiEngine(const sp<DataSource> &dataSource,
+ MidiEngine(DataSourceBase *dataSource,
const sp<MetaData> &fileMetadata,
const sp<MetaData> &trackMetadata);
~MidiEngine();
@@ -52,8 +52,7 @@
class MidiExtractor : public MediaExtractor {
public:
- // Extractor assumes ownership of source
- explicit MidiExtractor(const sp<DataSource> &source);
+ explicit MidiExtractor(DataSourceBase *source);
virtual size_t countTracks();
virtual MediaSourceBase *getTrack(size_t index);
@@ -66,7 +65,7 @@
virtual ~MidiExtractor();
private:
- sp<DataSource> mDataSource;
+ DataSourceBase *mDataSource;
status_t mInitCheck;
sp<MetaData> mFileMetadata;
@@ -88,7 +87,7 @@
};
-bool SniffMidi(const sp<DataSource> &source, String8 *mimeType,
+bool SniffMidi(DataSourceBase *source, String8 *mimeType,
float *confidence, sp<AMessage> *);
} // namespace android
diff --git a/media/extractors/mkv/MatroskaExtractor.cpp b/media/extractors/mkv/MatroskaExtractor.cpp
index 6df0012..f61f7c7 100644
--- a/media/extractors/mkv/MatroskaExtractor.cpp
+++ b/media/extractors/mkv/MatroskaExtractor.cpp
@@ -21,7 +21,7 @@
#include "FLACDecoder.h"
#include "MatroskaExtractor.h"
-#include <media/DataSource.h>
+#include <media/DataSourceBase.h>
#include <media/MediaSourceBase.h>
#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/foundation/AUtils.h>
@@ -40,8 +40,8 @@
namespace android {
-struct DataSourceReader : public mkvparser::IMkvReader {
- explicit DataSourceReader(const sp<DataSource> &source)
+struct DataSourceBaseReader : public mkvparser::IMkvReader {
+ explicit DataSourceBaseReader(DataSourceBase *source)
: mSource(source) {
}
@@ -83,10 +83,10 @@
}
private:
- sp<DataSource> mSource;
+ DataSourceBase *mSource;
- DataSourceReader(const DataSourceReader &);
- DataSourceReader &operator=(const DataSourceReader &);
+ DataSourceBaseReader(const DataSourceBaseReader &);
+ DataSourceBaseReader &operator=(const DataSourceBaseReader &);
};
////////////////////////////////////////////////////////////////////////////////
@@ -852,9 +852,9 @@
////////////////////////////////////////////////////////////////////////////////
-MatroskaExtractor::MatroskaExtractor(const sp<DataSource> &source)
+MatroskaExtractor::MatroskaExtractor(DataSourceBase *source)
: mDataSource(source),
- mReader(new DataSourceReader(mDataSource)),
+ mReader(new DataSourceBaseReader(mDataSource)),
mSegment(NULL),
mExtractedThumbnails(false),
mIsWebm(false),
@@ -862,8 +862,8 @@
off64_t size;
mIsLiveStreaming =
(mDataSource->flags()
- & (DataSource::kWantsPrefetching
- | DataSource::kIsCachingDataSource))
+ & (DataSourceBase::kWantsPrefetching
+ | DataSourceBase::kIsCachingDataSource))
&& mDataSource->getSize(&size) != OK;
mkvparser::EBMLHeader ebmlHeader;
@@ -1548,9 +1548,9 @@
}
bool SniffMatroska(
- const sp<DataSource> &source, String8 *mimeType, float *confidence,
+ DataSourceBase *source, String8 *mimeType, float *confidence,
sp<AMessage> *) {
- DataSourceReader reader(source);
+ DataSourceBaseReader reader(source);
mkvparser::EBMLHeader ebmlHeader;
long long pos;
if (ebmlHeader.Parse(&reader, pos) < 0) {
@@ -1574,13 +1574,13 @@
1,
"Matroska Extractor",
[](
- const sp<DataSource> &source,
+ DataSourceBase *source,
String8 *mimeType,
float *confidence,
sp<AMessage> *meta __unused) -> MediaExtractor::CreatorFunc {
if (SniffMatroska(source, mimeType, confidence, meta)) {
return [](
- const sp<DataSource> &source,
+ DataSourceBase *source,
const sp<AMessage>& meta __unused) -> MediaExtractor* {
return new MatroskaExtractor(source);};
}
diff --git a/media/extractors/mkv/MatroskaExtractor.h b/media/extractors/mkv/MatroskaExtractor.h
index 54419bf..095452b 100644
--- a/media/extractors/mkv/MatroskaExtractor.h
+++ b/media/extractors/mkv/MatroskaExtractor.h
@@ -30,11 +30,11 @@
class String8;
class MetaData;
-struct DataSourceReader;
+struct DataSourceBaseReader;
struct MatroskaSource;
struct MatroskaExtractor : public MediaExtractor {
- explicit MatroskaExtractor(const sp<DataSource> &source);
+ explicit MatroskaExtractor(DataSourceBase *source);
virtual size_t countTracks();
@@ -76,8 +76,8 @@
Mutex mLock;
Vector<TrackInfo> mTracks;
- sp<DataSource> mDataSource;
- DataSourceReader *mReader;
+ DataSourceBase *mDataSource;
+ DataSourceBaseReader *mReader;
mkvparser::Segment *mSegment;
bool mExtractedThumbnails;
bool mIsLiveStreaming;
@@ -96,7 +96,7 @@
};
bool SniffMatroska(
- const sp<DataSource> &source, String8 *mimeType, float *confidence,
+ DataSourceBase *source, String8 *mimeType, float *confidence,
sp<AMessage> *);
} // namespace android
diff --git a/media/extractors/mp3/MP3Extractor.cpp b/media/extractors/mp3/MP3Extractor.cpp
index 7e27fd8..25d4deb 100644
--- a/media/extractors/mp3/MP3Extractor.cpp
+++ b/media/extractors/mp3/MP3Extractor.cpp
@@ -24,7 +24,7 @@
#include "VBRISeeker.h"
#include "XINGSeeker.h"
-#include <media/DataSource.h>
+#include <media/DataSourceBase.h>
#include <media/MediaSourceBase.h>
#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/foundation/AMessage.h>
@@ -46,7 +46,7 @@
static const uint32_t kMask = 0xfffe0c00;
static bool Resync(
- const sp<DataSource> &source, uint32_t match_header,
+ DataSourceBase *source, uint32_t match_header,
off64_t *inout_pos, off64_t *post_id3_pos, uint32_t *out_header) {
if (post_id3_pos != NULL) {
*post_id3_pos = 0;
@@ -212,7 +212,7 @@
class MP3Source : public MediaSourceBase {
public:
MP3Source(
- const sp<MetaData> &meta, const sp<DataSource> &source,
+ const sp<MetaData> &meta, DataSourceBase *source,
off64_t first_frame_pos, uint32_t fixed_header,
const sp<MP3Seeker> &seeker);
@@ -230,7 +230,7 @@
private:
static const size_t kMaxFrameSize;
sp<MetaData> mMeta;
- sp<DataSource> mDataSource;
+ DataSourceBase *mDataSource;
off64_t mFirstFramePos;
uint32_t mFixedHeader;
off64_t mCurrentPos;
@@ -247,7 +247,7 @@
};
MP3Extractor::MP3Extractor(
- const sp<DataSource> &source, const sp<AMessage> &meta)
+ DataSourceBase *source, const sp<AMessage> &meta)
: mInitCheck(NO_INIT),
mDataSource(source),
mFirstFramePos(-1),
@@ -436,7 +436,7 @@
// Set our max frame size to the nearest power of 2 above this size (aka, 4kB)
const size_t MP3Source::kMaxFrameSize = (1 << 12); /* 4096 bytes */
MP3Source::MP3Source(
- const sp<MetaData> &meta, const sp<DataSource> &source,
+ const sp<MetaData> &meta, DataSourceBase *source,
off64_t first_frame_pos, uint32_t fixed_header,
const sp<MP3Seeker> &seeker)
: mMeta(meta),
@@ -667,13 +667,13 @@
}
static MediaExtractor* CreateExtractor(
- const sp<DataSource> &source,
+ DataSourceBase *source,
const sp<AMessage>& meta) {
return new MP3Extractor(source, meta);
}
static MediaExtractor::CreatorFunc Sniff(
- const sp<DataSource> &source, String8 *mimeType,
+ DataSourceBase *source, String8 *mimeType,
float *confidence, sp<AMessage> *meta) {
off64_t pos = 0;
off64_t post_id3_pos;
diff --git a/media/extractors/mp3/MP3Extractor.h b/media/extractors/mp3/MP3Extractor.h
index 3b3387d..6257112 100644
--- a/media/extractors/mp3/MP3Extractor.h
+++ b/media/extractors/mp3/MP3Extractor.h
@@ -24,14 +24,13 @@
namespace android {
struct AMessage;
-class DataSource;
+class DataSourceBase;
struct MP3Seeker;
class String8;
class MP3Extractor : public MediaExtractor {
public:
- // Extractor assumes ownership of "source".
- MP3Extractor(const sp<DataSource> &source, const sp<AMessage> &meta);
+ MP3Extractor(DataSourceBase *source, const sp<AMessage> &meta);
virtual size_t countTracks();
virtual MediaSourceBase *getTrack(size_t index);
@@ -43,7 +42,7 @@
private:
status_t mInitCheck;
- sp<DataSource> mDataSource;
+ DataSourceBase *mDataSource;
off64_t mFirstFramePos;
sp<MetaData> mMeta;
uint32_t mFixedHeader;
@@ -54,7 +53,7 @@
};
bool SniffMP3(
- const sp<DataSource> &source, String8 *mimeType, float *confidence,
+ DataSourceBase *source, String8 *mimeType, float *confidence,
sp<AMessage> *meta);
} // namespace android
diff --git a/media/extractors/mp3/VBRISeeker.cpp b/media/extractors/mp3/VBRISeeker.cpp
index e7db6fd..51c5d1f 100644
--- a/media/extractors/mp3/VBRISeeker.cpp
+++ b/media/extractors/mp3/VBRISeeker.cpp
@@ -27,7 +27,7 @@
#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/foundation/ByteUtils.h>
-#include <media/DataSource.h>
+#include <media/DataSourceBase.h>
namespace android {
@@ -37,7 +37,7 @@
// static
sp<VBRISeeker> VBRISeeker::CreateFromSource(
- const sp<DataSource> &source, off64_t post_id3_pos) {
+ DataSourceBase *source, off64_t post_id3_pos) {
off64_t pos = post_id3_pos;
uint8_t header[4];
diff --git a/media/extractors/mp3/VBRISeeker.h b/media/extractors/mp3/VBRISeeker.h
index 87258b0..e46af36 100644
--- a/media/extractors/mp3/VBRISeeker.h
+++ b/media/extractors/mp3/VBRISeeker.h
@@ -24,11 +24,11 @@
namespace android {
-class DataSource;
+class DataSourceBase;
struct VBRISeeker : public MP3Seeker {
static sp<VBRISeeker> CreateFromSource(
- const sp<DataSource> &source, off64_t post_id3_pos);
+ DataSourceBase *source, off64_t post_id3_pos);
virtual bool getDuration(int64_t *durationUs);
virtual bool getOffsetForTime(int64_t *timeUs, off64_t *pos);
diff --git a/media/extractors/mp3/XINGSeeker.cpp b/media/extractors/mp3/XINGSeeker.cpp
index fa59701..adfa8d2 100644
--- a/media/extractors/mp3/XINGSeeker.cpp
+++ b/media/extractors/mp3/XINGSeeker.cpp
@@ -21,7 +21,7 @@
#include <media/stagefright/foundation/avc_utils.h>
#include <media/stagefright/foundation/ByteUtils.h>
-#include <media/DataSource.h>
+#include <media/DataSourceBase.h>
namespace android {
@@ -77,7 +77,7 @@
// static
sp<XINGSeeker> XINGSeeker::CreateFromSource(
- const sp<DataSource> &source, off64_t first_frame_pos) {
+ DataSourceBase *source, off64_t first_frame_pos) {
sp<XINGSeeker> seeker = new XINGSeeker;
seeker->mFirstFramePos = first_frame_pos;
diff --git a/media/extractors/mp3/XINGSeeker.h b/media/extractors/mp3/XINGSeeker.h
index 37077c4..db847bc 100644
--- a/media/extractors/mp3/XINGSeeker.h
+++ b/media/extractors/mp3/XINGSeeker.h
@@ -22,11 +22,11 @@
namespace android {
-class DataSource;
+class DataSourceBase;
struct XINGSeeker : public MP3Seeker {
static sp<XINGSeeker> CreateFromSource(
- const sp<DataSource> &source, off64_t first_frame_pos);
+ DataSourceBase *source, off64_t first_frame_pos);
virtual bool getDuration(int64_t *durationUs);
virtual bool getOffsetForTime(int64_t *timeUs, off64_t *pos);
diff --git a/media/extractors/mp4/ItemTable.cpp b/media/extractors/mp4/ItemTable.cpp
index 85c66b2..cef5f4a 100644
--- a/media/extractors/mp4/ItemTable.cpp
+++ b/media/extractors/mp4/ItemTable.cpp
@@ -18,7 +18,7 @@
#define LOG_TAG "ItemTable"
#include <ItemTable.h>
-#include <media/DataSource.h>
+#include <media/DataSourceBase.h>
#include <media/stagefright/MetaData.h>
#include <media/stagefright/MediaErrors.h>
#include <media/stagefright/foundation/ABuffer.h>
@@ -87,7 +87,7 @@
struct Box {
protected:
- Box(const sp<DataSource> source, uint32_t type) :
+ Box(DataSourceBase *source, uint32_t type) :
mDataSource(source), mType(type) {}
virtual ~Box() {}
@@ -99,14 +99,14 @@
inline uint32_t type() const { return mType; }
- inline sp<DataSource> source() const { return mDataSource; }
+ inline DataSourceBase *source() const { return mDataSource; }
status_t parseChunk(off64_t *offset);
status_t parseChunks(off64_t offset, size_t size);
private:
- sp<DataSource> mDataSource;
+ DataSourceBase *mDataSource;
uint32_t mType;
};
@@ -181,7 +181,7 @@
struct FullBox : public Box {
protected:
- FullBox(const sp<DataSource> source, uint32_t type) :
+ FullBox(DataSourceBase *source, uint32_t type) :
Box(source, type), mVersion(0), mFlags(0) {}
inline uint8_t version() const { return mVersion; }
@@ -216,7 +216,7 @@
//
struct PitmBox : public FullBox {
- PitmBox(const sp<DataSource> source) :
+ PitmBox(DataSourceBase *source) :
FullBox(source, FOURCC('p', 'i', 't', 'm')) {}
status_t parse(off64_t offset, size_t size, uint32_t *primaryItemId);
@@ -296,7 +296,7 @@
};
struct IlocBox : public FullBox {
- IlocBox(const sp<DataSource> source, KeyedVector<uint32_t, ItemLoc> *itemLocs) :
+ IlocBox(DataSourceBase *source, KeyedVector<uint32_t, ItemLoc> *itemLocs) :
FullBox(source, FOURCC('i', 'l', 'o', 'c')),
mItemLocs(itemLocs), mHasConstructMethod1(false) {}
@@ -466,7 +466,7 @@
//
struct ItemReference : public Box, public RefBase {
- ItemReference(const sp<DataSource> source, uint32_t type, uint32_t itemIdSize) :
+ ItemReference(DataSourceBase *source, uint32_t type, uint32_t itemIdSize) :
Box(source, type), mItemId(0), mRefIdSize(itemIdSize) {}
status_t parse(off64_t offset, size_t size);
@@ -575,7 +575,7 @@
}
struct IrefBox : public FullBox {
- IrefBox(const sp<DataSource> source, Vector<sp<ItemReference> > *itemRefs) :
+ IrefBox(DataSourceBase *source, Vector<sp<ItemReference> > *itemRefs) :
FullBox(source, FOURCC('i', 'r', 'e', 'f')), mRefIdSize(0), mItemRefs(itemRefs) {}
status_t parse(off64_t offset, size_t size);
@@ -637,7 +637,7 @@
};
struct IspeBox : public FullBox, public ItemProperty {
- IspeBox(const sp<DataSource> source) :
+ IspeBox(DataSourceBase *source) :
FullBox(source, FOURCC('i', 's', 'p', 'e')), mWidth(0), mHeight(0) {}
status_t parse(off64_t offset, size_t size) override;
@@ -673,7 +673,7 @@
}
struct HvccBox : public Box, public ItemProperty {
- HvccBox(const sp<DataSource> source) :
+ HvccBox(DataSourceBase *source) :
Box(source, FOURCC('h', 'v', 'c', 'C')) {}
status_t parse(off64_t offset, size_t size) override;
@@ -706,7 +706,7 @@
}
struct IrotBox : public Box, public ItemProperty {
- IrotBox(const sp<DataSource> source) :
+ IrotBox(DataSourceBase *source) :
Box(source, FOURCC('i', 'r', 'o', 't')), mAngle(0) {}
status_t parse(off64_t offset, size_t size) override;
@@ -735,7 +735,7 @@
}
struct ColrBox : public Box, public ItemProperty {
- ColrBox(const sp<DataSource> source) :
+ ColrBox(DataSourceBase *source) :
Box(source, FOURCC('c', 'o', 'l', 'r')) {}
status_t parse(off64_t offset, size_t size) override;
@@ -783,7 +783,7 @@
}
struct IpmaBox : public FullBox {
- IpmaBox(const sp<DataSource> source, Vector<AssociationEntry> *associations) :
+ IpmaBox(DataSourceBase *source, Vector<AssociationEntry> *associations) :
FullBox(source, FOURCC('i', 'p', 'm', 'a')), mAssociations(associations) {}
status_t parse(off64_t offset, size_t size);
@@ -857,7 +857,7 @@
}
struct IpcoBox : public Box {
- IpcoBox(const sp<DataSource> source, Vector<sp<ItemProperty> > *properties) :
+ IpcoBox(DataSourceBase *source, Vector<sp<ItemProperty> > *properties) :
Box(source, FOURCC('i', 'p', 'c', 'o')), mItemProperties(properties) {}
status_t parse(off64_t offset, size_t size);
@@ -914,7 +914,7 @@
}
struct IprpBox : public Box {
- IprpBox(const sp<DataSource> source,
+ IprpBox(DataSourceBase *source,
Vector<sp<ItemProperty> > *properties,
Vector<AssociationEntry> *associations) :
Box(source, FOURCC('i', 'p', 'r', 'p')),
@@ -971,7 +971,7 @@
};
struct InfeBox : public FullBox {
- InfeBox(const sp<DataSource> source) :
+ InfeBox(DataSourceBase *source) :
FullBox(source, FOURCC('i', 'n', 'f', 'e')) {}
status_t parse(off64_t offset, size_t size, ItemInfo *itemInfo);
@@ -1075,7 +1075,7 @@
}
struct IinfBox : public FullBox {
- IinfBox(const sp<DataSource> source, Vector<ItemInfo> *itemInfos) :
+ IinfBox(DataSourceBase *source, Vector<ItemInfo> *itemInfos) :
FullBox(source, FOURCC('i', 'i', 'n', 'f')),
mItemInfos(itemInfos), mHasGrids(false) {}
@@ -1144,7 +1144,7 @@
//////////////////////////////////////////////////////////////////
-ItemTable::ItemTable(const sp<DataSource> &source)
+ItemTable::ItemTable(DataSourceBase *source)
: mDataSource(source),
mPrimaryItemId(0),
mIdatOffset(0),
diff --git a/media/extractors/mp4/ItemTable.h b/media/extractors/mp4/ItemTable.h
index 3d2e2ae..f4a69cc 100644
--- a/media/extractors/mp4/ItemTable.h
+++ b/media/extractors/mp4/ItemTable.h
@@ -25,7 +25,7 @@
namespace android {
-class DataSource;
+class DataSourceBase;
class MetaData;
namespace heif {
@@ -44,7 +44,7 @@
class ItemTable : public RefBase {
public:
- explicit ItemTable(const sp<DataSource> &source);
+ explicit ItemTable(DataSourceBase *source);
status_t parse(uint32_t type, off64_t offset, size_t size);
@@ -60,7 +60,7 @@
~ItemTable();
private:
- sp<DataSource> mDataSource;
+ DataSourceBase *mDataSource;
KeyedVector<uint32_t, ItemLoc> mItemLocs;
Vector<ItemInfo> mItemInfos;
diff --git a/media/extractors/mp4/MPEG4Extractor.cpp b/media/extractors/mp4/MPEG4Extractor.cpp
index 9f21db6..30dda13 100644
--- a/media/extractors/mp4/MPEG4Extractor.cpp
+++ b/media/extractors/mp4/MPEG4Extractor.cpp
@@ -69,7 +69,7 @@
public:
// Caller retains ownership of both "dataSource" and "sampleTable".
MPEG4Source(const sp<MetaData> &format,
- const sp<DataSource> &dataSource,
+ DataSourceBase *dataSource,
int32_t timeScale,
const sp<SampleTable> &sampleTable,
Vector<SidxEntry> &sidx,
@@ -93,7 +93,7 @@
Mutex mLock;
sp<MetaData> mFormat;
- sp<DataSource> mDataSource;
+ DataSourceBase *mDataSource;
int32_t mTimescale;
sp<SampleTable> mSampleTable;
uint32_t mCurrentSampleIndex;
@@ -186,47 +186,51 @@
// all remaining requests to the wrapped datasource.
// This is used to cache the full sampletable metadata for a single track,
// possibly wrapping multiple times to cover all tracks, i.e.
-// Each MPEG4DataSource caches the sampletable metadata for a single track.
+// Each CachedRangedDataSource caches the sampletable metadata for a single track.
-struct MPEG4DataSource : public DataSource {
- explicit MPEG4DataSource(const sp<DataSource> &source);
+struct CachedRangedDataSource : public DataSourceBase {
+ explicit CachedRangedDataSource(DataSourceBase *source);
+ virtual ~CachedRangedDataSource();
virtual status_t initCheck() const;
virtual ssize_t readAt(off64_t offset, void *data, size_t size);
virtual status_t getSize(off64_t *size);
virtual uint32_t flags();
- status_t setCachedRange(off64_t offset, size_t size);
+ status_t setCachedRange(off64_t offset, size_t size, bool assumeSourceOwnershipOnSuccess);
-protected:
- virtual ~MPEG4DataSource();
private:
Mutex mLock;
- sp<DataSource> mSource;
+ DataSourceBase *mSource;
+ bool mOwnsDataSource;
off64_t mCachedOffset;
size_t mCachedSize;
uint8_t *mCache;
void clearCache();
- MPEG4DataSource(const MPEG4DataSource &);
- MPEG4DataSource &operator=(const MPEG4DataSource &);
+ CachedRangedDataSource(const CachedRangedDataSource &);
+ CachedRangedDataSource &operator=(const CachedRangedDataSource &);
};
-MPEG4DataSource::MPEG4DataSource(const sp<DataSource> &source)
+CachedRangedDataSource::CachedRangedDataSource(DataSourceBase *source)
: mSource(source),
+ mOwnsDataSource(false),
mCachedOffset(0),
mCachedSize(0),
mCache(NULL) {
}
-MPEG4DataSource::~MPEG4DataSource() {
+CachedRangedDataSource::~CachedRangedDataSource() {
clearCache();
+ if (mOwnsDataSource) {
+ delete (CachedRangedDataSource*)mSource;
+ }
}
-void MPEG4DataSource::clearCache() {
+void CachedRangedDataSource::clearCache() {
if (mCache) {
free(mCache);
mCache = NULL;
@@ -236,11 +240,11 @@
mCachedSize = 0;
}
-status_t MPEG4DataSource::initCheck() const {
+status_t CachedRangedDataSource::initCheck() const {
return mSource->initCheck();
}
-ssize_t MPEG4DataSource::readAt(off64_t offset, void *data, size_t size) {
+ssize_t CachedRangedDataSource::readAt(off64_t offset, void *data, size_t size) {
Mutex::Autolock autoLock(mLock);
if (isInRange(mCachedOffset, mCachedSize, offset, size)) {
@@ -251,15 +255,17 @@
return mSource->readAt(offset, data, size);
}
-status_t MPEG4DataSource::getSize(off64_t *size) {
+status_t CachedRangedDataSource::getSize(off64_t *size) {
return mSource->getSize(size);
}
-uint32_t MPEG4DataSource::flags() {
+uint32_t CachedRangedDataSource::flags() {
return mSource->flags();
}
-status_t MPEG4DataSource::setCachedRange(off64_t offset, size_t size) {
+status_t CachedRangedDataSource::setCachedRange(off64_t offset,
+ size_t size,
+ bool assumeSourceOwnershipOnSuccess) {
Mutex::Autolock autoLock(mLock);
clearCache();
@@ -280,7 +286,7 @@
return ERROR_IO;
}
-
+ mOwnsDataSource = assumeSourceOwnershipOnSuccess;
return OK;
}
@@ -334,11 +340,12 @@
return false;
}
-MPEG4Extractor::MPEG4Extractor(const sp<DataSource> &source, const char *mime)
+MPEG4Extractor::MPEG4Extractor(DataSourceBase *source, const char *mime)
: mMoofOffset(0),
mMoofFound(false),
mMdatFound(false),
mDataSource(source),
+ mCachedSource(NULL),
mInitCheck(NO_INIT),
mHeaderTimescale(0),
mIsQT(false),
@@ -354,10 +361,6 @@
}
MPEG4Extractor::~MPEG4Extractor() {
- release();
-}
-
-void MPEG4Extractor::release() {
Track *track = mFirstTrack;
while (track) {
Track *next = track->next;
@@ -381,10 +384,7 @@
}
mPssh.clear();
- if (mDataSource != NULL) {
- mDataSource->close();
- mDataSource.clear();
- }
+ delete mCachedSource;
}
uint32_t MPEG4Extractor::flags() const {
@@ -692,14 +692,14 @@
// Reads an encoded integer 7 bits at a time until it encounters the high bit clear.
static int32_t readSize(off64_t offset,
- const sp<DataSource> &DataSource, uint8_t *numOfBytes) {
+ DataSourceBase *DataSourceBase, uint8_t *numOfBytes) {
uint32_t size = 0;
uint8_t data;
bool moreData = true;
*numOfBytes = 0;
while (moreData) {
- if (DataSource->readAt(offset, &data, 1) < 1) {
+ if (DataSourceBase->readAt(offset, &data, 1) < 1) {
return -1;
}
offset ++;
@@ -1045,13 +1045,17 @@
ALOGV("sampleTable chunk is %" PRIu64 " bytes long.", chunk_size);
if (mDataSource->flags()
- & (DataSource::kWantsPrefetching
- | DataSource::kIsCachingDataSource)) {
- sp<MPEG4DataSource> cachedSource =
- new MPEG4DataSource(mDataSource);
+ & (DataSourceBase::kWantsPrefetching
+ | DataSourceBase::kIsCachingDataSource)) {
+ CachedRangedDataSource *cachedSource =
+ new CachedRangedDataSource(mDataSource);
- if (cachedSource->setCachedRange(*offset, chunk_size) == OK) {
- mDataSource = cachedSource;
+ if (cachedSource->setCachedRange(
+ *offset, chunk_size,
+ mCachedSource != NULL /* assume ownership on success */) == OK) {
+ mDataSource = mCachedSource = cachedSource;
+ } else {
+ delete cachedSource;
}
}
@@ -3890,7 +3894,7 @@
MPEG4Source::MPEG4Source(
const sp<MetaData> &format,
- const sp<DataSource> &dataSource,
+ DataSourceBase *dataSource,
int32_t timeScale,
const sp<SampleTable> &sampleTable,
Vector<SidxEntry> &sidx,
@@ -5379,7 +5383,7 @@
}
static bool LegacySniffMPEG4(
- const sp<DataSource> &source, String8 *mimeType, float *confidence) {
+ DataSourceBase *source, String8 *mimeType, float *confidence) {
uint8_t header[8];
ssize_t n = source->readAt(4, header, sizeof(header));
@@ -5446,7 +5450,7 @@
// (end of the 'moov' atom) and report it to the caller as part of
// the metadata.
static bool BetterSniffMPEG4(
- const sp<DataSource> &source, String8 *mimeType, float *confidence,
+ DataSourceBase *source, String8 *mimeType, float *confidence,
sp<AMessage> *meta) {
// We scan up to 128 bytes to identify this file as an MP4.
static const off64_t kMaxScanOffset = 128ll;
@@ -5563,13 +5567,13 @@
}
static MediaExtractor* CreateExtractor(
- const sp<DataSource> &source,
+ DataSourceBase *source,
const sp<AMessage>& meta __unused) {
return new MPEG4Extractor(source);
}
static MediaExtractor::CreatorFunc Sniff(
- const sp<DataSource> &source,
+ DataSourceBase *source,
String8 *mimeType,
float *confidence,
sp<AMessage> *meta) {
diff --git a/media/extractors/mp4/MPEG4Extractor.h b/media/extractors/mp4/MPEG4Extractor.h
index e947b87..644c430 100644
--- a/media/extractors/mp4/MPEG4Extractor.h
+++ b/media/extractors/mp4/MPEG4Extractor.h
@@ -20,7 +20,7 @@
#include <arpa/inet.h>
-#include <media/DataSource.h>
+#include <media/DataSourceBase.h>
#include <media/MediaExtractor.h>
#include <media/stagefright/foundation/AString.h>
#include <utils/List.h>
@@ -29,7 +29,8 @@
namespace android {
struct AMessage;
-class DataSource;
+class DataSourceBase;
+struct CachedRangedDataSource;
class SampleTable;
class String8;
namespace heif {
@@ -52,8 +53,7 @@
class MPEG4Extractor : public MediaExtractor {
public:
- // Extractor assumes ownership of "source".
- explicit MPEG4Extractor(const sp<DataSource> &source, const char *mime = NULL);
+ explicit MPEG4Extractor(DataSourceBase *source, const char *mime = NULL);
virtual size_t countTracks();
virtual MediaSourceBase *getTrack(size_t index);
@@ -62,7 +62,6 @@
virtual sp<MetaData> getMetaData();
virtual uint32_t flags() const;
virtual const char * name() { return "MPEG4Extractor"; }
- virtual void release();
// for DRM
virtual char* getDrmTrackInfo(size_t trackID, int *len);
@@ -98,7 +97,8 @@
Vector<Trex> mTrex;
- sp<DataSource> mDataSource;
+ DataSourceBase *mDataSource;
+ CachedRangedDataSource *mCachedSource;
status_t mInitCheck;
uint32_t mHeaderTimescale;
bool mIsQT;
@@ -160,7 +160,7 @@
};
bool SniffMPEG4(
- const sp<DataSource> &source, String8 *mimeType, float *confidence,
+ DataSourceBase *source, String8 *mimeType, float *confidence,
sp<AMessage> *);
} // namespace android
diff --git a/media/extractors/mp4/SampleIterator.cpp b/media/extractors/mp4/SampleIterator.cpp
index c194397..93ee7c6 100644
--- a/media/extractors/mp4/SampleIterator.cpp
+++ b/media/extractors/mp4/SampleIterator.cpp
@@ -22,7 +22,7 @@
#include <arpa/inet.h>
-#include <media/DataSource.h>
+#include <media/DataSourceBase.h>
#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/foundation/ByteUtils.h>
diff --git a/media/extractors/mp4/SampleTable.cpp b/media/extractors/mp4/SampleTable.cpp
index 378d63a..81c353e 100644
--- a/media/extractors/mp4/SampleTable.cpp
+++ b/media/extractors/mp4/SampleTable.cpp
@@ -25,7 +25,7 @@
#include <arpa/inet.h>
-#include <media/DataSource.h>
+#include <media/DataSourceBase.h>
#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/foundation/ByteUtils.h>
@@ -114,7 +114,7 @@
////////////////////////////////////////////////////////////////////////////////
-SampleTable::SampleTable(const sp<DataSource> &source)
+SampleTable::SampleTable(DataSourceBase *source)
: mDataSource(source),
mChunkOffsetOffset(-1),
mChunkOffsetType(0),
diff --git a/media/extractors/mp4/SampleTable.h b/media/extractors/mp4/SampleTable.h
index 466e26b..e4e974b 100644
--- a/media/extractors/mp4/SampleTable.h
+++ b/media/extractors/mp4/SampleTable.h
@@ -27,12 +27,12 @@
namespace android {
-class DataSource;
+class DataSourceBase;
struct SampleIterator;
class SampleTable : public RefBase {
public:
- explicit SampleTable(const sp<DataSource> &source);
+ explicit SampleTable(DataSourceBase *source);
bool isValid() const;
@@ -99,7 +99,7 @@
// Limit the total size of all internal tables to 200MiB.
static const size_t kMaxTotalSize = 200 * (1 << 20);
- sp<DataSource> mDataSource;
+ DataSourceBase *mDataSource;
Mutex mLock;
off64_t mChunkOffsetOffset;
diff --git a/media/extractors/mpeg2/ExtractorBundle.cpp b/media/extractors/mpeg2/ExtractorBundle.cpp
index d5682e9..443d685 100644
--- a/media/extractors/mpeg2/ExtractorBundle.cpp
+++ b/media/extractors/mpeg2/ExtractorBundle.cpp
@@ -34,18 +34,18 @@
1,
"MPEG2-PS/TS Extractor",
[](
- const sp<DataSource> &source,
+ DataSourceBase *source,
String8 *mimeType,
float *confidence,
sp<AMessage> *meta __unused) -> MediaExtractor::CreatorFunc {
if (SniffMPEG2TS(source, mimeType, confidence, meta)) {
return [](
- const sp<DataSource> &source,
+ DataSourceBase *source,
const sp<AMessage>& meta __unused) -> MediaExtractor* {
return new MPEG2TSExtractor(source);};
} else if (SniffMPEG2PS(source, mimeType, confidence, meta)) {
return [](
- const sp<DataSource> &source,
+ DataSourceBase *source,
const sp<AMessage>& meta __unused) -> MediaExtractor* {
return new MPEG2PSExtractor(source);};
}
diff --git a/media/extractors/mpeg2/MPEG2PSExtractor.cpp b/media/extractors/mpeg2/MPEG2PSExtractor.cpp
index 0978387..697e44f 100644
--- a/media/extractors/mpeg2/MPEG2PSExtractor.cpp
+++ b/media/extractors/mpeg2/MPEG2PSExtractor.cpp
@@ -23,7 +23,7 @@
#include "mpeg2ts/AnotherPacketSource.h"
#include "mpeg2ts/ESQueue.h"
-#include <media/DataSource.h>
+#include <media/DataSourceBase.h>
#include <media/MediaSourceBase.h>
#include <media/stagefright/foundation/ABitReader.h>
#include <media/stagefright/foundation/ABuffer.h>
@@ -94,7 +94,7 @@
////////////////////////////////////////////////////////////////////////////////
-MPEG2PSExtractor::MPEG2PSExtractor(const sp<DataSource> &source)
+MPEG2PSExtractor::MPEG2PSExtractor(DataSourceBase *source)
: mDataSource(source),
mOffset(0),
mFinalResult(OK),
@@ -751,7 +751,7 @@
////////////////////////////////////////////////////////////////////////////////
bool SniffMPEG2PS(
- const sp<DataSource> &source, String8 *mimeType, float *confidence,
+ DataSourceBase *source, String8 *mimeType, float *confidence,
sp<AMessage> *) {
uint8_t header[5];
if (source->readAt(0, header, sizeof(header)) < (ssize_t)sizeof(header)) {
diff --git a/media/extractors/mpeg2/MPEG2PSExtractor.h b/media/extractors/mpeg2/MPEG2PSExtractor.h
index f8a97ef..adf719a 100644
--- a/media/extractors/mpeg2/MPEG2PSExtractor.h
+++ b/media/extractors/mpeg2/MPEG2PSExtractor.h
@@ -31,7 +31,7 @@
class String8;
struct MPEG2PSExtractor : public MediaExtractor {
- explicit MPEG2PSExtractor(const sp<DataSource> &source);
+ explicit MPEG2PSExtractor(DataSourceBase *source);
virtual size_t countTracks();
virtual MediaSourceBase *getTrack(size_t index);
@@ -50,7 +50,7 @@
struct WrappedTrack;
mutable Mutex mLock;
- sp<DataSource> mDataSource;
+ DataSourceBase *mDataSource;
off64_t mOffset;
status_t mFinalResult;
@@ -72,7 +72,7 @@
};
bool SniffMPEG2PS(
- const sp<DataSource> &source, String8 *mimeType, float *confidence,
+ DataSourceBase *source, String8 *mimeType, float *confidence,
sp<AMessage> *);
} // namespace android
diff --git a/media/extractors/mpeg2/MPEG2TSExtractor.cpp b/media/extractors/mpeg2/MPEG2TSExtractor.cpp
index b24e8db..6d0b1cc 100644
--- a/media/extractors/mpeg2/MPEG2TSExtractor.cpp
+++ b/media/extractors/mpeg2/MPEG2TSExtractor.cpp
@@ -22,7 +22,7 @@
#include "MPEG2TSExtractor.h"
-#include <media/DataSource.h>
+#include <media/DataSourceBase.h>
#include <media/IStreamSource.h>
#include <media/MediaSourceBase.h>
#include <media/stagefright/foundation/ABuffer.h>
@@ -121,7 +121,7 @@
////////////////////////////////////////////////////////////////////////////////
-MPEG2TSExtractor::MPEG2TSExtractor(const sp<DataSource> &source)
+MPEG2TSExtractor::MPEG2TSExtractor(DataSourceBase *source)
: mDataSource(source),
mParser(new ATSParser),
mLastSyncEvent(0),
@@ -367,7 +367,7 @@
}
status_t MPEG2TSExtractor::estimateDurationsFromTimesUsAtEnd() {
- if (!(mDataSource->flags() & DataSource::kIsLocalFileSource)) {
+ if (!(mDataSource->flags() & DataSourceBase::kIsLocalFileSource)) {
return ERROR_UNSUPPORTED;
}
@@ -646,7 +646,7 @@
////////////////////////////////////////////////////////////////////////////////
bool SniffMPEG2TS(
- const sp<DataSource> &source, String8 *mimeType, float *confidence,
+ DataSourceBase *source, String8 *mimeType, float *confidence,
sp<AMessage> *) {
for (int i = 0; i < 5; ++i) {
char header;
diff --git a/media/extractors/mpeg2/MPEG2TSExtractor.h b/media/extractors/mpeg2/MPEG2TSExtractor.h
index 362f016..57cb675 100644
--- a/media/extractors/mpeg2/MPEG2TSExtractor.h
+++ b/media/extractors/mpeg2/MPEG2TSExtractor.h
@@ -32,12 +32,12 @@
struct AMessage;
struct AnotherPacketSource;
struct ATSParser;
-class DataSource;
+class DataSourceBase;
struct MPEG2TSSource;
class String8;
struct MPEG2TSExtractor : public MediaExtractor {
- explicit MPEG2TSExtractor(const sp<DataSource> &source);
+ explicit MPEG2TSExtractor(DataSourceBase *source);
virtual size_t countTracks();
virtual MediaSourceBase *getTrack(size_t index);
@@ -55,7 +55,7 @@
mutable Mutex mLock;
- sp<DataSource> mDataSource;
+ DataSourceBase *mDataSource;
sp<ATSParser> mParser;
@@ -79,9 +79,9 @@
// Try to feed more data from source to parser.
// |isInit| means this function is called inside init(). This is a signal to
// save SyncEvent so that init() can add SyncPoint after it updates |mSourceImpls|.
- // This function returns OK if expected amount of data is fed from DataSource to
+ // This function returns OK if expected amount of data is fed from DataSourceBase to
// parser and is successfully parsed. Otherwise, various error codes could be
- // returned, e.g., ERROR_END_OF_STREAM, or no data availalbe from DataSource, or
+ // returned, e.g., ERROR_END_OF_STREAM, or no data availalbe from DataSourceBase, or
// the data has syntax error during parsing, etc.
status_t feedMore(bool isInit = false);
status_t seek(int64_t seekTimeUs,
@@ -100,7 +100,7 @@
};
bool SniffMPEG2TS(
- const sp<DataSource> &source, String8 *mimeType, float *confidence,
+ DataSourceBase *source, String8 *mimeType, float *confidence,
sp<AMessage> *);
} // namespace android
diff --git a/media/extractors/ogg/OggExtractor.cpp b/media/extractors/ogg/OggExtractor.cpp
index f62ec47..1d04bed 100644
--- a/media/extractors/ogg/OggExtractor.cpp
+++ b/media/extractors/ogg/OggExtractor.cpp
@@ -21,7 +21,7 @@
#include "OggExtractor.h"
#include <cutils/properties.h>
-#include <media/DataSource.h>
+#include <media/DataSourceBase.h>
#include <media/MediaSourceBase.h>
#include <media/stagefright/foundation/ABuffer.h>
#include <media/stagefright/foundation/ADebug.h>
@@ -69,7 +69,7 @@
struct MyOggExtractor {
MyOggExtractor(
- const sp<DataSource> &source,
+ DataSourceBase *source,
const char *mimeType,
size_t numHeaders,
int64_t seekPreRollUs);
@@ -105,7 +105,7 @@
int64_t mTimeUs;
};
- sp<DataSource> mSource;
+ DataSourceBase *mSource;
off64_t mOffset;
Page mCurrentPage;
uint64_t mCurGranulePosition;
@@ -164,7 +164,7 @@
};
struct MyVorbisExtractor : public MyOggExtractor {
- explicit MyVorbisExtractor(const sp<DataSource> &source)
+ explicit MyVorbisExtractor(DataSourceBase *source)
: MyOggExtractor(source,
MEDIA_MIMETYPE_AUDIO_VORBIS,
/* numHeaders */ 3,
@@ -192,7 +192,7 @@
static const int32_t kOpusSampleRate = 48000;
static const int64_t kOpusSeekPreRollUs = 80000; // 80 ms
- explicit MyOpusExtractor(const sp<DataSource> &source)
+ explicit MyOpusExtractor(DataSourceBase *source)
: MyOggExtractor(source, MEDIA_MIMETYPE_AUDIO_OPUS, /*numHeaders*/ 2, kOpusSeekPreRollUs),
mChannelCount(0),
mCodecDelay(0),
@@ -294,7 +294,7 @@
////////////////////////////////////////////////////////////////////////////////
MyOggExtractor::MyOggExtractor(
- const sp<DataSource> &source,
+ DataSourceBase *source,
const char *mimeType,
size_t numHeaders,
int64_t seekPreRollUs)
@@ -852,7 +852,7 @@
off64_t size;
uint64_t lastGranulePosition;
- if (!(mSource->flags() & DataSource::kIsCachingDataSource)
+ if (!(mSource->flags() & DataSourceBase::kIsCachingDataSource)
&& mSource->getSize(&size) == OK
&& findPrevGranulePosition(size, &lastGranulePosition) == OK) {
// Let's assume it's cheap to seek to the end.
@@ -1315,7 +1315,7 @@
////////////////////////////////////////////////////////////////////////////////
-OggExtractor::OggExtractor(const sp<DataSource> &source)
+OggExtractor::OggExtractor(DataSourceBase *source)
: mDataSource(source),
mInitCheck(NO_INIT),
mImpl(NULL) {
@@ -1370,13 +1370,13 @@
}
static MediaExtractor* CreateExtractor(
- const sp<DataSource> &source,
+ DataSourceBase *source,
const sp<AMessage>& meta __unused) {
return new OggExtractor(source);
}
static MediaExtractor::CreatorFunc Sniff(
- const sp<DataSource> &source,
+ DataSourceBase *source,
String8 *mimeType,
float *confidence,
sp<AMessage> *) {
diff --git a/media/extractors/ogg/OggExtractor.h b/media/extractors/ogg/OggExtractor.h
index 126428c..c9c37eb 100644
--- a/media/extractors/ogg/OggExtractor.h
+++ b/media/extractors/ogg/OggExtractor.h
@@ -24,14 +24,14 @@
namespace android {
struct AMessage;
-class DataSource;
+class DataSourceBase;
class String8;
struct MyOggExtractor;
struct OggSource;
struct OggExtractor : public MediaExtractor {
- explicit OggExtractor(const sp<DataSource> &source);
+ explicit OggExtractor(DataSourceBase *source);
virtual size_t countTracks();
virtual MediaSourceBase *getTrack(size_t index);
@@ -46,7 +46,7 @@
private:
friend struct OggSource;
- sp<DataSource> mDataSource;
+ DataSourceBase *mDataSource;
status_t mInitCheck;
MyOggExtractor *mImpl;
@@ -56,7 +56,7 @@
};
bool SniffOgg(
- const sp<DataSource> &source, String8 *mimeType, float *confidence,
+ DataSourceBase *source, String8 *mimeType, float *confidence,
sp<AMessage> *);
} // namespace android
diff --git a/media/extractors/wav/WAVExtractor.cpp b/media/extractors/wav/WAVExtractor.cpp
index cf22c66..105a37f 100644
--- a/media/extractors/wav/WAVExtractor.cpp
+++ b/media/extractors/wav/WAVExtractor.cpp
@@ -21,7 +21,7 @@
#include "WAVExtractor.h"
#include <audio_utils/primitives.h>
-#include <media/DataSource.h>
+#include <media/DataSourceBase.h>
#include <media/MediaSourceBase.h>
#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/MediaBufferGroup.h>
@@ -57,7 +57,7 @@
struct WAVSource : public MediaSourceBase {
WAVSource(
- const sp<DataSource> &dataSource,
+ DataSourceBase *dataSource,
const sp<MetaData> &meta,
uint16_t waveFormat,
int32_t bitsPerSample,
@@ -78,7 +78,7 @@
private:
static const size_t kMaxFrameSize;
- sp<DataSource> mDataSource;
+ DataSourceBase *mDataSource;
sp<MetaData> mMeta;
uint16_t mWaveFormat;
int32_t mSampleRate;
@@ -94,7 +94,7 @@
WAVSource &operator=(const WAVSource &);
};
-WAVExtractor::WAVExtractor(const sp<DataSource> &source)
+WAVExtractor::WAVExtractor(DataSourceBase *source)
: mDataSource(source),
mValidFormat(false),
mChannelMask(CHANNEL_MASK_USE_CHANNEL_ORDER) {
@@ -348,7 +348,7 @@
const size_t WAVSource::kMaxFrameSize = 32768;
WAVSource::WAVSource(
- const sp<DataSource> &dataSource,
+ DataSourceBase *dataSource,
const sp<MetaData> &meta,
uint16_t waveFormat,
int32_t bitsPerSample,
@@ -545,13 +545,13 @@
////////////////////////////////////////////////////////////////////////////////
static MediaExtractor* CreateExtractor(
- const sp<DataSource> &source,
+ DataSourceBase *source,
const sp<AMessage>& meta __unused) {
return new WAVExtractor(source);
}
static MediaExtractor::CreatorFunc Sniff(
- const sp<DataSource> &source,
+ DataSourceBase *source,
String8 *mimeType,
float *confidence,
sp<AMessage> *) {
diff --git a/media/extractors/wav/WAVExtractor.h b/media/extractors/wav/WAVExtractor.h
index 47c3c40..67661ed 100644
--- a/media/extractors/wav/WAVExtractor.h
+++ b/media/extractors/wav/WAVExtractor.h
@@ -24,13 +24,12 @@
namespace android {
struct AMessage;
-class DataSource;
+class DataSourceBase;
class String8;
class WAVExtractor : public MediaExtractor {
public:
- // Extractor assumes ownership of "source".
- explicit WAVExtractor(const sp<DataSource> &source);
+ explicit WAVExtractor(DataSourceBase *source);
virtual size_t countTracks();
virtual MediaSourceBase *getTrack(size_t index);
@@ -42,7 +41,7 @@
virtual ~WAVExtractor();
private:
- sp<DataSource> mDataSource;
+ DataSourceBase *mDataSource;
status_t mInitCheck;
bool mValidFormat;
uint16_t mWaveFormat;
diff --git a/media/libmedia/IMediaExtractor.cpp b/media/libmedia/IMediaExtractor.cpp
index a8a7b82..51ccb5a 100644
--- a/media/libmedia/IMediaExtractor.cpp
+++ b/media/libmedia/IMediaExtractor.cpp
@@ -39,8 +39,7 @@
SETMEDIACAS,
SETUID,
NAME,
- GETMETRICS,
- RELEASE,
+ GETMETRICS
};
class BpMediaExtractor : public BpInterface<IMediaExtractor> {
@@ -140,13 +139,6 @@
ALOGV("name NOT IMPLEMENTED");
return NULL;
}
-
- virtual void release() {
- ALOGV("release");
- Parcel data, reply;
- data.writeInterfaceToken(BpMediaExtractor::getInterfaceDescriptor());
- remote()->transact(RELEASE, data, &reply);
- }
};
IMPLEMENT_META_INTERFACE(MediaExtractor, "android.media.IMediaExtractor");
@@ -224,12 +216,6 @@
reply->writeInt32(setMediaCas(casToken));
return OK;
}
- case RELEASE: {
- ALOGV("release");
- CHECK_INTERFACE(IMediaExtractor, data, reply);
- release();
- return OK;
- }
default:
return BBinder::onTransact(code, data, reply, flags);
}
diff --git a/media/libmedia/MidiIoWrapper.cpp b/media/libmedia/MidiIoWrapper.cpp
index 4e5d67f..0896e75 100644
--- a/media/libmedia/MidiIoWrapper.cpp
+++ b/media/libmedia/MidiIoWrapper.cpp
@@ -47,7 +47,7 @@
mLength = size;
}
-MidiIoWrapper::MidiIoWrapper(const sp<DataSource> &source) {
+MidiIoWrapper::MidiIoWrapper(DataSourceBase *source) {
ALOGV("MidiIoWrapper(DataSource)");
mFd = -1;
mDataSource = source;
diff --git a/media/libmedia/include/media/IMediaExtractor.h b/media/libmedia/include/media/IMediaExtractor.h
index 44f8c1d..9899429 100644
--- a/media/libmedia/include/media/IMediaExtractor.h
+++ b/media/libmedia/include/media/IMediaExtractor.h
@@ -68,8 +68,6 @@
virtual void setUID(uid_t uid) = 0;
virtual const char * name() = 0;
-
- virtual void release() = 0;
};
diff --git a/media/libmedia/include/media/MidiIoWrapper.h b/media/libmedia/include/media/MidiIoWrapper.h
index 2754b2c..a27b410 100644
--- a/media/libmedia/include/media/MidiIoWrapper.h
+++ b/media/libmedia/include/media/MidiIoWrapper.h
@@ -19,7 +19,7 @@
#include <libsonivox/eas_types.h>
-#include <media/DataSource.h>
+#include <media/DataSourceBase.h>
namespace android {
@@ -27,7 +27,7 @@
public:
MidiIoWrapper(const char *path);
MidiIoWrapper(int fd, off64_t offset, int64_t size);
- MidiIoWrapper(const sp<DataSource> &source);
+ MidiIoWrapper(DataSourceBase *source);
~MidiIoWrapper();
@@ -40,7 +40,7 @@
int mFd;
off64_t mBase;
int64_t mLength;
- sp<DataSource> mDataSource;
+ DataSourceBase *mDataSource;
EAS_FILE mEasFile;
};
diff --git a/media/libmediaextractor/Android.bp b/media/libmediaextractor/Android.bp
index 4071fba..8f4ba70 100644
--- a/media/libmediaextractor/Android.bp
+++ b/media/libmediaextractor/Android.bp
@@ -23,7 +23,7 @@
],
srcs: [
- "DataSource.cpp",
+ "DataSourceBase.cpp",
"MediaBuffer.cpp",
"MediaBufferGroup.cpp",
"MediaSourceBase.cpp",
diff --git a/media/libmediaextractor/DataSource.cpp b/media/libmediaextractor/DataSourceBase.cpp
similarity index 77%
rename from media/libmediaextractor/DataSource.cpp
rename to media/libmediaextractor/DataSourceBase.cpp
index 72959c6..d3af4eb 100644
--- a/media/libmediaextractor/DataSource.cpp
+++ b/media/libmediaextractor/DataSourceBase.cpp
@@ -14,16 +14,16 @@
* limitations under the License.
*/
//#define LOG_NDEBUG 0
-#define LOG_TAG "DataSource"
+#define LOG_TAG "DataSourceBase"
-#include <media/DataSource.h>
+#include <media/DataSourceBase.h>
#include <media/stagefright/foundation/ByteUtils.h>
#include <media/stagefright/MediaErrors.h>
#include <utils/String8.h>
namespace android {
-bool DataSource::getUInt16(off64_t offset, uint16_t *x) {
+bool DataSourceBase::getUInt16(off64_t offset, uint16_t *x) {
*x = 0;
uint8_t byte[2];
@@ -36,7 +36,7 @@
return true;
}
-bool DataSource::getUInt24(off64_t offset, uint32_t *x) {
+bool DataSourceBase::getUInt24(off64_t offset, uint32_t *x) {
*x = 0;
uint8_t byte[3];
@@ -49,7 +49,7 @@
return true;
}
-bool DataSource::getUInt32(off64_t offset, uint32_t *x) {
+bool DataSourceBase::getUInt32(off64_t offset, uint32_t *x) {
*x = 0;
uint32_t tmp;
@@ -62,7 +62,7 @@
return true;
}
-bool DataSource::getUInt64(off64_t offset, uint64_t *x) {
+bool DataSourceBase::getUInt64(off64_t offset, uint64_t *x) {
*x = 0;
uint64_t tmp;
@@ -75,7 +75,7 @@
return true;
}
-bool DataSource::getUInt16Var(off64_t offset, uint16_t *x, size_t size) {
+bool DataSourceBase::getUInt16Var(off64_t offset, uint16_t *x, size_t size) {
if (size == 2) {
return getUInt16(offset, x);
}
@@ -89,7 +89,7 @@
return false;
}
-bool DataSource::getUInt32Var(off64_t offset, uint32_t *x, size_t size) {
+bool DataSourceBase::getUInt32Var(off64_t offset, uint32_t *x, size_t size) {
if (size == 4) {
return getUInt32(offset, x);
}
@@ -103,7 +103,7 @@
return false;
}
-bool DataSource::getUInt64Var(off64_t offset, uint64_t *x, size_t size) {
+bool DataSourceBase::getUInt64Var(off64_t offset, uint64_t *x, size_t size) {
if (size == 8) {
return getUInt64(offset, x);
}
@@ -117,13 +117,13 @@
return false;
}
-status_t DataSource::getSize(off64_t *size) {
+status_t DataSourceBase::getSize(off64_t *size) {
*size = 0;
return ERROR_UNSUPPORTED;
}
-String8 DataSource::getMIMEType() const {
+String8 DataSourceBase::getMIMEType() const {
return String8("application/octet-stream");
}
diff --git a/media/libmediaextractor/include/media/DataSource.h b/media/libmediaextractor/include/media/DataSource.h
index 9f00e0a..a066183 100644
--- a/media/libmediaextractor/include/media/DataSource.h
+++ b/media/libmediaextractor/include/media/DataSource.h
@@ -20,75 +20,21 @@
#include <sys/types.h>
#include <media/stagefright/MediaErrors.h>
+#include <media/DataSourceBase.h>
#include <utils/Errors.h>
#include <utils/RefBase.h>
#include <utils/threads.h>
#include <drm/DrmManagerClient.h>
+
namespace android {
class String8;
-class DataSource : public RefBase {
+class DataSource : public DataSourceBase, public virtual RefBase {
public:
- enum Flags {
- kWantsPrefetching = 1,
- kStreamedFromLocalHost = 2,
- kIsCachingDataSource = 4,
- kIsHTTPBasedSource = 8,
- kIsLocalFileSource = 16,
- };
-
DataSource() {}
- virtual status_t initCheck() const = 0;
-
- // Returns the number of bytes read, or -1 on failure. It's not an error if
- // this returns zero; it just means the given offset is equal to, or
- // beyond, the end of the source.
- virtual ssize_t readAt(off64_t offset, void *data, size_t size) = 0;
-
- // Convenience methods:
- bool getUInt16(off64_t offset, uint16_t *x);
- bool getUInt24(off64_t offset, uint32_t *x); // 3 byte int, returned as a 32-bit int
- bool getUInt32(off64_t offset, uint32_t *x);
- bool getUInt64(off64_t offset, uint64_t *x);
-
- // read either int<N> or int<2N> into a uint<2N>_t, size is the int size in bytes.
- bool getUInt16Var(off64_t offset, uint16_t *x, size_t size);
- bool getUInt32Var(off64_t offset, uint32_t *x, size_t size);
- bool getUInt64Var(off64_t offset, uint64_t *x, size_t size);
-
- // May return ERROR_UNSUPPORTED.
- virtual status_t getSize(off64_t *size);
-
- virtual uint32_t flags() {
- return 0;
- }
-
- virtual String8 toString() {
- return String8("<unspecified>");
- }
-
- virtual status_t reconnectAtOffset(off64_t /*offset*/) {
- return ERROR_UNSUPPORTED;
- }
-
- ////////////////////////////////////////////////////////////////////////////
-
- // for DRM
- virtual sp<DecryptHandle> DrmInitialization(const char * /*mime*/ = NULL) {
- return NULL;
- }
-
- virtual String8 getUri() {
- return String8();
- }
-
- virtual String8 getMIMEType() const;
-
- virtual void close() {};
-
protected:
virtual ~DataSource() {}
diff --git a/media/libmediaextractor/include/media/DataSourceBase.h b/media/libmediaextractor/include/media/DataSourceBase.h
new file mode 100644
index 0000000..f964137
--- /dev/null
+++ b/media/libmediaextractor/include/media/DataSourceBase.h
@@ -0,0 +1,160 @@
+/*
+ * Copyright (C) 2009 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 DATA_SOURCE_BASE_H_
+
+#define DATA_SOURCE_BASE_H_
+
+#include <sys/types.h>
+#include <media/stagefright/MediaErrors.h>
+#include <utils/Errors.h>
+#include <utils/threads.h>
+#include <drm/DrmManagerClient.h>
+
+namespace android {
+
+class String8;
+
+class DataSourceBase {
+public:
+ enum Flags {
+ kWantsPrefetching = 1,
+ kStreamedFromLocalHost = 2,
+ kIsCachingDataSource = 4,
+ kIsHTTPBasedSource = 8,
+ kIsLocalFileSource = 16,
+ };
+
+ DataSourceBase() {}
+
+ virtual status_t initCheck() const = 0;
+
+ // Returns the number of bytes read, or -1 on failure. It's not an error if
+ // this returns zero; it just means the given offset is equal to, or
+ // beyond, the end of the source.
+ virtual ssize_t readAt(off64_t offset, void *data, size_t size) = 0;
+
+ // Convenience methods:
+ bool getUInt16(off64_t offset, uint16_t *x);
+ bool getUInt24(off64_t offset, uint32_t *x); // 3 byte int, returned as a 32-bit int
+ bool getUInt32(off64_t offset, uint32_t *x);
+ bool getUInt64(off64_t offset, uint64_t *x);
+
+ // read either int<N> or int<2N> into a uint<2N>_t, size is the int size in bytes.
+ bool getUInt16Var(off64_t offset, uint16_t *x, size_t size);
+ bool getUInt32Var(off64_t offset, uint32_t *x, size_t size);
+ bool getUInt64Var(off64_t offset, uint64_t *x, size_t size);
+
+ // Reads in "count" entries of type T into vector *x.
+ // Returns true if "count" entries can be read.
+ // If fewer than "count" entries can be read, return false. In this case,
+ // the output vector *x will still have those entries that were read. Call
+ // x->size() to obtain the number of entries read.
+ // The optional parameter chunkSize specifies how many entries should be
+ // read from the data source at one time into a temporary buffer. Increasing
+ // chunkSize can improve the performance at the cost of extra memory usage.
+ // The default value for chunkSize is set to read at least 4k bytes at a
+ // time, depending on sizeof(T).
+ template <typename T>
+ bool getVector(off64_t offset, Vector<T>* x, size_t count,
+ size_t chunkSize = (4095 / sizeof(T)) + 1);
+
+ // May return ERROR_UNSUPPORTED.
+ virtual status_t getSize(off64_t *size);
+
+ virtual uint32_t flags() {
+ return 0;
+ }
+
+ virtual String8 toString() {
+ return String8("<unspecified>");
+ }
+
+ virtual status_t reconnectAtOffset(off64_t /*offset*/) {
+ return ERROR_UNSUPPORTED;
+ }
+
+ ////////////////////////////////////////////////////////////////////////////
+
+ // for DRM
+ virtual sp<DecryptHandle> DrmInitialization(const char * /*mime*/ = NULL) {
+ return NULL;
+ }
+
+ virtual String8 getUri() {
+ return String8();
+ }
+
+ virtual String8 getMIMEType() const;
+
+ virtual void close() {};
+
+protected:
+ virtual ~DataSourceBase() {}
+
+private:
+ DataSourceBase(const DataSourceBase &);
+ DataSourceBase &operator=(const DataSourceBase &);
+};
+
+template <typename T>
+bool DataSourceBase::getVector(off64_t offset, Vector<T>* x, size_t count,
+ size_t chunkSize)
+{
+ x->clear();
+ if (chunkSize == 0) {
+ return false;
+ }
+ if (count == 0) {
+ return true;
+ }
+
+ T tmp[chunkSize];
+ ssize_t numBytesRead;
+ size_t numBytesPerChunk = chunkSize * sizeof(T);
+ size_t i;
+
+ for (i = 0; i + chunkSize < count; i += chunkSize) {
+ // This loops is executed when more than chunkSize records need to be
+ // read.
+ numBytesRead = this->readAt(offset, (void*)&tmp, numBytesPerChunk);
+ if (numBytesRead == -1) { // If readAt() returns -1, there is an error.
+ return false;
+ }
+ if (static_cast<size_t>(numBytesRead) < numBytesPerChunk) {
+ // This case is triggered when the stream ends before the whole
+ // chunk is read.
+ x->appendArray(tmp, (size_t)numBytesRead / sizeof(T));
+ return false;
+ }
+ x->appendArray(tmp, chunkSize);
+ offset += numBytesPerChunk;
+ }
+
+ // There are (count - i) more records to read.
+ // Right now, (count - i) <= chunkSize.
+ // We do the same thing as above, but with chunkSize replaced by count - i.
+ numBytesRead = this->readAt(offset, (void*)&tmp, (count - i) * sizeof(T));
+ if (numBytesRead == -1) {
+ return false;
+ }
+ x->appendArray(tmp, (size_t)numBytesRead / sizeof(T));
+ return x->size() == count;
+}
+
+} // namespace android
+
+#endif // DATA_SOURCE_BASE_H_
diff --git a/media/libmediaextractor/include/media/MediaExtractor.h b/media/libmediaextractor/include/media/MediaExtractor.h
index 27581f3..60495ec 100644
--- a/media/libmediaextractor/include/media/MediaExtractor.h
+++ b/media/libmediaextractor/include/media/MediaExtractor.h
@@ -27,7 +27,7 @@
namespace android {
-class DataSource;
+class DataSourceBase;
class MetaData;
class String8;
struct AMessage;
@@ -87,15 +87,14 @@
virtual const char * name() { return "<unspecified>"; }
- virtual void release() {}
typedef MediaExtractor* (*CreatorFunc)(
- const sp<DataSource> &source, const sp<AMessage> &meta);
+ DataSourceBase *source, const sp<AMessage> &meta);
// The sniffer can optionally fill in "meta" with an AMessage containing
// a dictionary of values that helps the corresponding extractor initialize
// its state without duplicating effort already exerted by the sniffer.
typedef CreatorFunc (*SnifferFunc)(
- const sp<DataSource> &source, String8 *mimeType,
+ DataSourceBase *source, String8 *mimeType,
float *confidence, sp<AMessage> *meta);
typedef struct {
diff --git a/media/libstagefright/CallbackDataSource.cpp b/media/libstagefright/CallbackDataSource.cpp
index f479644..71b737b 100644
--- a/media/libstagefright/CallbackDataSource.cpp
+++ b/media/libstagefright/CallbackDataSource.cpp
@@ -21,6 +21,7 @@
#include "include/CallbackDataSource.h"
#include <binder/IMemory.h>
+#include <binder/IPCThreadState.h>
#include <media/IDataSource.h>
#include <media/stagefright/foundation/ADebug.h>
@@ -34,7 +35,10 @@
mIsClosed(false) {
// Set up the buffer to read into.
mMemory = mIDataSource->getIMemory();
- mName = String8::format("CallbackDataSource(%s)", mIDataSource->toString().string());
+ mName = String8::format("CallbackDataSource(%d->%d, %s)",
+ getpid(),
+ IPCThreadState::self()->getCallingPid(),
+ mIDataSource->toString().string());
}
diff --git a/media/libstagefright/InterfaceUtils.cpp b/media/libstagefright/InterfaceUtils.cpp
index 284e63b..70fbbd7 100644
--- a/media/libstagefright/InterfaceUtils.cpp
+++ b/media/libstagefright/InterfaceUtils.cpp
@@ -38,11 +38,13 @@
}
sp<IMediaExtractor> CreateIMediaExtractorFromMediaExtractor(
- MediaExtractor *extractor, const sp<RefBase> &plugin) {
+ MediaExtractor *extractor,
+ const sp<DataSource> &source,
+ const sp<RefBase> &plugin) {
if (extractor == nullptr) {
return nullptr;
}
- return RemoteMediaExtractor::wrap(extractor, plugin);
+ return RemoteMediaExtractor::wrap(extractor, source, plugin);
}
sp<MediaSource> CreateMediaSourceFromIMediaSource(const sp<IMediaSource> &source) {
diff --git a/media/libstagefright/MediaExtractorFactory.cpp b/media/libstagefright/MediaExtractorFactory.cpp
index e79696c..bb72167 100644
--- a/media/libstagefright/MediaExtractorFactory.cpp
+++ b/media/libstagefright/MediaExtractorFactory.cpp
@@ -118,7 +118,7 @@
String8 tmp;
float confidence;
sp<ExtractorPlugin> plugin;
- creator = sniff(source, &tmp, &confidence, &meta, plugin);
+ creator = sniff(source.get(), &tmp, &confidence, &meta, plugin);
if (!creator) {
ALOGV("FAILED to autodetect media content.");
return NULL;
@@ -128,8 +128,8 @@
ALOGV("Autodetected media content as '%s' with confidence %.2f",
mime, confidence);
- MediaExtractor *ret = creator(source, meta);
- return CreateIMediaExtractorFromMediaExtractor(ret, plugin);
+ MediaExtractor *ret = creator(source.get(), meta);
+ return CreateIMediaExtractorFromMediaExtractor(ret, source, plugin);
}
//static
@@ -165,7 +165,7 @@
// static
MediaExtractor::CreatorFunc MediaExtractorFactory::sniff(
- const sp<DataSource> &source, String8 *mimeType, float *confidence, sp<AMessage> *meta,
+ DataSourceBase *source, String8 *mimeType, float *confidence, sp<AMessage> *meta,
sp<ExtractorPlugin> &plugin) {
*mimeType = "";
*confidence = 0.0f;
diff --git a/media/libstagefright/RemoteMediaExtractor.cpp b/media/libstagefright/RemoteMediaExtractor.cpp
index 3ebee51..601c9fa 100644
--- a/media/libstagefright/RemoteMediaExtractor.cpp
+++ b/media/libstagefright/RemoteMediaExtractor.cpp
@@ -37,9 +37,12 @@
static const char *kExtractorFormat = "android.media.mediaextractor.fmt";
RemoteMediaExtractor::RemoteMediaExtractor(
- MediaExtractor *extractor, const sp<RefBase> &plugin)
+ MediaExtractor *extractor,
+ const sp<DataSource> &source,
+ const sp<RefBase> &plugin)
:mExtractor(extractor),
- mExtractorPlugin(plugin) {
+ mSource(source),
+ mExtractorPlugin(plugin) {
mAnalyticsItem = nullptr;
if (MEDIA_LOG) {
@@ -67,6 +70,8 @@
RemoteMediaExtractor::~RemoteMediaExtractor() {
delete mExtractor;
+ mSource->close();
+ mSource.clear();
mExtractorPlugin = nullptr;
// log the current record, provided it has some information worth recording
if (MEDIA_LOG) {
@@ -129,19 +134,17 @@
return mExtractor->name();
}
-void RemoteMediaExtractor::release() {
- return mExtractor->release();
-}
-
////////////////////////////////////////////////////////////////////////////////
// static
sp<IMediaExtractor> RemoteMediaExtractor::wrap(
- MediaExtractor *extractor, const sp<RefBase> &plugin) {
+ MediaExtractor *extractor,
+ const sp<DataSource> &source,
+ const sp<RefBase> &plugin) {
if (extractor == nullptr) {
return nullptr;
}
- return new RemoteMediaExtractor(extractor, plugin);
+ return new RemoteMediaExtractor(extractor, source, plugin);
}
} // namespace android
diff --git a/media/libstagefright/StagefrightMetadataRetriever.cpp b/media/libstagefright/StagefrightMetadataRetriever.cpp
index e2db0f5..179e0e6 100644
--- a/media/libstagefright/StagefrightMetadataRetriever.cpp
+++ b/media/libstagefright/StagefrightMetadataRetriever.cpp
@@ -47,12 +47,6 @@
StagefrightMetadataRetriever::~StagefrightMetadataRetriever() {
ALOGV("~StagefrightMetadataRetriever()");
clearMetadata();
- // Explicitly release extractor before continuing with the destructor,
- // some extractors might need to callback to close off the DataSource
- // and we need to make sure it's still there.
- if (mExtractor != NULL) {
- mExtractor->release();
- }
if (mSource != NULL) {
mSource->close();
}
diff --git a/media/libstagefright/id3/ID3.cpp b/media/libstagefright/id3/ID3.cpp
index 61403be..f4bba59 100644
--- a/media/libstagefright/id3/ID3.cpp
+++ b/media/libstagefright/id3/ID3.cpp
@@ -30,7 +30,7 @@
static const size_t kMaxMetadataSize = 3 * 1024 * 1024;
-struct MemorySource : public DataSource {
+struct MemorySource : public DataSourceBase {
MemorySource(const uint8_t *data, size_t size)
: mData(data),
mSize(size) {
@@ -56,7 +56,7 @@
DISALLOW_EVIL_CONSTRUCTORS(MemorySource);
};
-ID3::ID3(const sp<DataSource> &source, bool ignoreV1, off64_t offset)
+ID3::ID3(DataSourceBase *source, bool ignoreV1, off64_t offset)
: mIsValid(false),
mData(NULL),
mSize(0),
@@ -77,7 +77,7 @@
mFirstFrameOffset(0),
mVersion(ID3_UNKNOWN),
mRawSize(0) {
- sp<MemorySource> source = new (std::nothrow) MemorySource(data, size);
+ MemorySource *source = new (std::nothrow) MemorySource(data, size);
if (source == NULL)
return;
@@ -87,6 +87,7 @@
if (!mIsValid && !ignoreV1) {
mIsValid = parseV1(source);
}
+ delete source;
}
ID3::~ID3() {
@@ -118,7 +119,7 @@
return true;
}
-bool ID3::parseV2(const sp<DataSource> &source, off64_t offset) {
+bool ID3::parseV2(DataSourceBase *source, off64_t offset) {
struct id3_header {
char id[3];
uint8_t version_major;
@@ -960,7 +961,7 @@
return NULL;
}
-bool ID3::parseV1(const sp<DataSource> &source) {
+bool ID3::parseV1(DataSourceBase *source) {
const size_t V1_TAG_SIZE = 128;
off64_t size;
diff --git a/media/libstagefright/id3/testid3.cpp b/media/libstagefright/id3/testid3.cpp
index 442a3ff..86e6adf 100644
--- a/media/libstagefright/id3/testid3.cpp
+++ b/media/libstagefright/id3/testid3.cpp
@@ -72,7 +72,7 @@
sp<FileSource> file = new FileSource(path);
CHECK_EQ(file->initCheck(), (status_t)OK);
- ID3 tag(file);
+ ID3 tag(file.get());
if (!tag.isValid()) {
printf("FAIL %s\n", path);
} else {
diff --git a/media/libstagefright/include/ID3.h b/media/libstagefright/include/ID3.h
index 11682f8..7c2391e 100644
--- a/media/libstagefright/include/ID3.h
+++ b/media/libstagefright/include/ID3.h
@@ -22,7 +22,7 @@
namespace android {
-class DataSource;
+class DataSourceBase;
class String8;
struct ID3 {
@@ -35,7 +35,7 @@
ID3_V2_4,
};
- explicit ID3(const sp<DataSource> &source, bool ignoreV1 = false, off64_t offset = 0);
+ explicit ID3(DataSourceBase *source, bool ignoreV1 = false, off64_t offset = 0);
ID3(const uint8_t *data, size_t size, bool ignoreV1 = false);
~ID3();
@@ -85,8 +85,8 @@
// only valid for IDV2+
size_t mRawSize;
- bool parseV1(const sp<DataSource> &source);
- bool parseV2(const sp<DataSource> &source, off64_t offset);
+ bool parseV1(DataSourceBase *source);
+ bool parseV2(DataSourceBase *source, off64_t offset);
void removeUnsynchronization();
bool removeUnsynchronizationV2_4(bool iTunesHack);
diff --git a/media/libstagefright/include/media/stagefright/InterfaceUtils.h b/media/libstagefright/include/media/stagefright/InterfaceUtils.h
index ceeaf31..568c735 100644
--- a/media/libstagefright/include/media/stagefright/InterfaceUtils.h
+++ b/media/libstagefright/include/media/stagefright/InterfaceUtils.h
@@ -41,7 +41,9 @@
// Creates an IMediaExtractor wrapper to the given MediaExtractor.
sp<IMediaExtractor> CreateIMediaExtractorFromMediaExtractor(
- MediaExtractor *extractor, const sp<RefBase> &plugin);
+ MediaExtractor *extractor,
+ const sp<DataSource> &source,
+ const sp<RefBase> &plugin);
// Creates a MediaSource which wraps the given IMediaSource object.
sp<MediaSource> CreateMediaSourceFromIMediaSource(const sp<IMediaSource> &source);
diff --git a/media/libstagefright/include/media/stagefright/MediaExtractorFactory.h b/media/libstagefright/include/media/stagefright/MediaExtractorFactory.h
index 4610359..4d2f4f0 100644
--- a/media/libstagefright/include/media/stagefright/MediaExtractorFactory.h
+++ b/media/libstagefright/include/media/stagefright/MediaExtractorFactory.h
@@ -56,7 +56,7 @@
static void RegisterExtractor(
const sp<ExtractorPlugin> &plugin, List<sp<ExtractorPlugin>> &pluginList);
- static MediaExtractor::CreatorFunc sniff(const sp<DataSource> &source,
+ static MediaExtractor::CreatorFunc sniff(DataSourceBase *source,
String8 *mimeType, float *confidence, sp<AMessage> *meta,
sp<ExtractorPlugin> &plugin);
diff --git a/media/libstagefright/include/media/stagefright/RemoteMediaExtractor.h b/media/libstagefright/include/media/stagefright/RemoteMediaExtractor.h
index 78f3a84..22a8210 100644
--- a/media/libstagefright/include/media/stagefright/RemoteMediaExtractor.h
+++ b/media/libstagefright/include/media/stagefright/RemoteMediaExtractor.h
@@ -28,7 +28,10 @@
// IMediaExtractor wrapper to the MediaExtractor.
class RemoteMediaExtractor : public BnMediaExtractor {
public:
- static sp<IMediaExtractor> wrap(MediaExtractor *extractor, const sp<RefBase> &plugin);
+ static sp<IMediaExtractor> wrap(
+ MediaExtractor *extractor,
+ const sp<DataSource> &source,
+ const sp<RefBase> &plugin);
virtual ~RemoteMediaExtractor();
virtual size_t countTracks();
@@ -41,15 +44,18 @@
virtual void setUID(uid_t uid);
virtual status_t setMediaCas(const HInterfaceToken &casToken);
virtual const char * name();
- virtual void release();
private:
MediaExtractor *mExtractor;
+ sp<DataSource> mSource;
sp<RefBase> mExtractorPlugin;
MediaAnalyticsItem *mAnalyticsItem;
- explicit RemoteMediaExtractor(MediaExtractor *extractor, const sp<RefBase> &plugin);
+ explicit RemoteMediaExtractor(
+ MediaExtractor *extractor,
+ const sp<DataSource> &source,
+ const sp<RefBase> &plugin);
DISALLOW_EVIL_CONSTRUCTORS(RemoteMediaExtractor);
};