cas: convert MediaCas to HIDL
- Remove AIDL interfaces.
- Replace usage with corresponding HIDL interfaces.
- Move MediaCasService implementation from frameworks/av
to hardware/interfaces/cas.
bug: 22804304
Change-Id: I56ab22565a43e91481ac2759ce69462bcc194046
diff --git a/drm/libmediadrm/Android.bp b/drm/libmediadrm/Android.bp
index 66f5fc2..1dd5139 100644
--- a/drm/libmediadrm/Android.bp
+++ b/drm/libmediadrm/Android.bp
@@ -5,26 +5,14 @@
cc_library_shared {
name: "libmediadrm",
- aidl: {
- local_include_dirs: ["aidl"],
- export_aidl_headers: true,
- },
srcs: [
- "aidl/android/media/ICas.aidl",
- "aidl/android/media/ICasListener.aidl",
- "aidl/android/media/IDescrambler.aidl",
- "aidl/android/media/IMediaCasService.aidl",
-
- "CasImpl.cpp",
- "DescramblerImpl.cpp",
"DrmPluginPath.cpp",
"DrmSessionManager.cpp",
"ICrypto.cpp",
"IDrm.cpp",
"IDrmClient.cpp",
"IMediaDrmService.cpp",
- "MediaCasDefs.cpp",
"SharedLibrary.cpp",
"DrmHal.cpp",
"CryptoHal.cpp",
diff --git a/drm/libmediadrm/CasImpl.cpp b/drm/libmediadrm/CasImpl.cpp
deleted file mode 100644
index 1a33bb0..0000000
--- a/drm/libmediadrm/CasImpl.cpp
+++ /dev/null
@@ -1,224 +0,0 @@
-
-/*
- * 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.
- */
-//#define LOG_NDEBUG 0
-#define LOG_TAG "CasImpl"
-
-#include <android/media/ICasListener.h>
-#include <media/cas/CasAPI.h>
-#include <media/CasImpl.h>
-#include <media/SharedLibrary.h>
-#include <utils/Log.h>
-
-namespace android {
-
-static Status getBinderStatus(status_t err) {
- if (err == OK) {
- return Status::ok();
- }
- if (err == BAD_VALUE) {
- return Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT);
- }
- if (err == INVALID_OPERATION) {
- return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE);
- }
- return Status::fromServiceSpecificError(err);
-}
-
-static String8 sessionIdToString(const CasSessionId &sessionId) {
- String8 result;
- for (size_t i = 0; i < sessionId.size(); i++) {
- result.appendFormat("%02x ", sessionId[i]);
- }
- if (result.isEmpty()) {
- result.append("(null)");
- }
- return result;
-}
-
-struct CasImpl::PluginHolder : public RefBase {
-public:
- explicit PluginHolder(CasPlugin *plugin) : mPlugin(plugin) {}
- ~PluginHolder() { if (mPlugin != NULL) delete mPlugin; }
- CasPlugin* get() { return mPlugin; }
-
-private:
- CasPlugin *mPlugin;
- DISALLOW_EVIL_CONSTRUCTORS(PluginHolder);
-};
-
-CasImpl::CasImpl(const sp<ICasListener> &listener)
- : mPluginHolder(NULL), mListener(listener) {
- ALOGV("CTOR");
-}
-
-CasImpl::~CasImpl() {
- ALOGV("DTOR");
- release();
-}
-
-//static
-void CasImpl::OnEvent(
- void *appData,
- int32_t event,
- int32_t arg,
- uint8_t *data,
- size_t size) {
- if (appData == NULL) {
- ALOGE("Invalid appData!");
- return;
- }
- CasImpl *casImpl = static_cast<CasImpl *>(appData);
- casImpl->onEvent(event, arg, data, size);
-}
-
-void CasImpl::init(const sp<SharedLibrary>& library, CasPlugin *plugin) {
- mLibrary = library;
- mPluginHolder = new PluginHolder(plugin);
-}
-
-void CasImpl::onEvent(
- int32_t event, int32_t arg, uint8_t *data, size_t size) {
- if (mListener == NULL) {
- return;
- }
-
- std::unique_ptr<CasData> eventData;
- if (data != NULL && size > 0) {
- eventData.reset(new CasData(data, data + size));
- }
-
- mListener->onEvent(event, arg, eventData);
-}
-
-Status CasImpl::setPrivateData(const CasData& pvtData) {
- ALOGV("setPrivateData");
- sp<PluginHolder> holder = mPluginHolder;
- if (holder == NULL) {
- return getBinderStatus(INVALID_OPERATION);
- }
- return getBinderStatus(holder->get()->setPrivateData(pvtData));
-}
-
-Status CasImpl::openSession(CasSessionId* sessionId) {
- ALOGV("openSession");
- sp<PluginHolder> holder = mPluginHolder;
- if (holder == NULL) {
- return getBinderStatus(INVALID_OPERATION);
- }
- status_t err = holder->get()->openSession(sessionId);
-
- ALOGV("openSession: session opened, sessionId=%s",
- sessionIdToString(*sessionId).string());
-
- return getBinderStatus(err);
-}
-
-Status CasImpl::setSessionPrivateData(
- const CasSessionId &sessionId, const CasData& pvtData) {
- ALOGV("setSessionPrivateData: sessionId=%s",
- sessionIdToString(sessionId).string());
- sp<PluginHolder> holder = mPluginHolder;
- if (holder == NULL) {
- return getBinderStatus(INVALID_OPERATION);
- }
- return getBinderStatus(holder->get()->setSessionPrivateData(sessionId, pvtData));
-}
-
-Status CasImpl::closeSession(const CasSessionId &sessionId) {
- ALOGV("closeSession: sessionId=%s",
- sessionIdToString(sessionId).string());
- sp<PluginHolder> holder = mPluginHolder;
- if (holder == NULL) {
- return getBinderStatus(INVALID_OPERATION);
- }
- return getBinderStatus(holder->get()->closeSession(sessionId));
-}
-
-Status CasImpl::processEcm(const CasSessionId &sessionId, const ParcelableCasData& ecm) {
- ALOGV("processEcm: sessionId=%s",
- sessionIdToString(sessionId).string());
- sp<PluginHolder> holder = mPluginHolder;
- if (holder == NULL) {
- return getBinderStatus(INVALID_OPERATION);
- }
-
- return getBinderStatus(holder->get()->processEcm(sessionId, ecm));
-}
-
-Status CasImpl::processEmm(const ParcelableCasData& emm) {
- ALOGV("processEmm");
- sp<PluginHolder> holder = mPluginHolder;
- if (holder == NULL) {
- return getBinderStatus(INVALID_OPERATION);
- }
-
- return getBinderStatus(holder->get()->processEmm(emm));
-}
-
-Status CasImpl::sendEvent(
- int32_t event, int32_t arg, const ::std::unique_ptr<CasData> &eventData) {
- ALOGV("sendEvent");
- sp<PluginHolder> holder = mPluginHolder;
- if (holder == NULL) {
- return getBinderStatus(INVALID_OPERATION);
- }
-
- status_t err;
- if (eventData == nullptr) {
- err = holder->get()->sendEvent(event, arg, CasData());
- } else {
- err = holder->get()->sendEvent(event, arg, *eventData);
- }
- return getBinderStatus(err);
-}
-
-Status CasImpl::provision(const String16& provisionString) {
- ALOGV("provision: provisionString=%s", String8(provisionString).string());
- sp<PluginHolder> holder = mPluginHolder;
- if (holder == NULL) {
- return getBinderStatus(INVALID_OPERATION);
- }
-
- return getBinderStatus(holder->get()->provision(String8(provisionString)));
-}
-
-Status CasImpl::refreshEntitlements(
- int32_t refreshType, const ::std::unique_ptr<CasData> &refreshData) {
- ALOGV("refreshEntitlements");
- sp<PluginHolder> holder = mPluginHolder;
- if (holder == NULL) {
- return getBinderStatus(INVALID_OPERATION);
- }
-
- status_t err;
- if (refreshData == nullptr) {
- err = holder->get()->refreshEntitlements(refreshType, CasData());
- } else {
- err = holder->get()->refreshEntitlements(refreshType, *refreshData);
- }
- return getBinderStatus(err);
-}
-
-Status CasImpl::release() {
- ALOGV("release: plugin=%p",
- mPluginHolder == NULL ? mPluginHolder->get() : NULL);
- mPluginHolder.clear();
- return Status::ok();
-}
-
-} // namespace android
-
diff --git a/drm/libmediadrm/DescramblerImpl.cpp b/drm/libmediadrm/DescramblerImpl.cpp
deleted file mode 100644
index 94e09e2..0000000
--- a/drm/libmediadrm/DescramblerImpl.cpp
+++ /dev/null
@@ -1,107 +0,0 @@
-
-/*
- * 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.
- */
-//#define LOG_NDEBUG 0
-#define LOG_TAG "DescramblerImpl"
-
-#include <media/cas/DescramblerAPI.h>
-#include <media/DescramblerImpl.h>
-#include <media/SharedLibrary.h>
-#include <utils/Log.h>
-#include <binder/IMemory.h>
-
-namespace android {
-
-static Status getBinderStatus(status_t err) {
- if (err == OK) {
- return Status::ok();
- }
- if (err == BAD_VALUE) {
- return Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT);
- }
- if (err == INVALID_OPERATION) {
- return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE);
- }
- return Status::fromServiceSpecificError(err);
-}
-
-static String8 sessionIdToString(const CasSessionId &sessionId) {
- String8 result;
- for (size_t i = 0; i < sessionId.size(); i++) {
- result.appendFormat("%02x ", sessionId[i]);
- }
- if (result.isEmpty()) {
- result.append("(null)");
- }
- return result;
-}
-
-DescramblerImpl::DescramblerImpl(
- const sp<SharedLibrary>& library, DescramblerPlugin *plugin) :
- mLibrary(library), mPlugin(plugin) {
- ALOGV("CTOR: mPlugin=%p", mPlugin);
-}
-
-DescramblerImpl::~DescramblerImpl() {
- ALOGV("DTOR: mPlugin=%p", mPlugin);
- release();
-}
-
-Status DescramblerImpl::setMediaCasSession(const CasSessionId& sessionId) {
- ALOGV("setMediaCasSession: sessionId=%s",
- sessionIdToString(sessionId).string());
-
- return getBinderStatus(mPlugin->setMediaCasSession(sessionId));
-}
-
-Status DescramblerImpl::requiresSecureDecoderComponent(
- const String16& mime, bool *result) {
- *result = mPlugin->requiresSecureDecoderComponent(String8(mime));
-
- return getBinderStatus(OK);
-}
-
-Status DescramblerImpl::descramble(
- const DescrambleInfo& info, int32_t *result) {
- ALOGV("descramble");
-
- *result = mPlugin->descramble(
- info.dstType != DescrambleInfo::kDestinationTypeVmPointer,
- info.scramblingControl,
- info.numSubSamples,
- info.subSamples,
- info.srcMem->pointer(),
- info.srcOffset,
- info.dstType == DescrambleInfo::kDestinationTypeVmPointer ?
- info.srcMem->pointer() : info.dstPtr,
- info.dstOffset,
- NULL);
-
- return getBinderStatus(*result >= 0 ? OK : *result);
-}
-
-Status DescramblerImpl::release() {
- ALOGV("release: mPlugin=%p", mPlugin);
-
- if (mPlugin != NULL) {
- delete mPlugin;
- mPlugin = NULL;
- }
- return Status::ok();
-}
-
-} // namespace android
-
diff --git a/drm/libmediadrm/MediaCasDefs.cpp b/drm/libmediadrm/MediaCasDefs.cpp
deleted file mode 100644
index 9c2ba38..0000000
--- a/drm/libmediadrm/MediaCasDefs.cpp
+++ /dev/null
@@ -1,184 +0,0 @@
-/*
- * 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.
- */
-//#define LOG_NDEBUG 0
-#define LOG_TAG "MediaCas"
-
-#include <media/MediaCasDefs.h>
-#include <utils/Log.h>
-#include <binder/IMemory.h>
-
-namespace android {
-namespace media {
-
-///////////////////////////////////////////////////////////////////////////////
-namespace MediaCas {
-
-status_t ParcelableCasData::readFromParcel(const Parcel* parcel) {
- return parcel->readByteVector(this);
-}
-
-status_t ParcelableCasData::writeToParcel(Parcel* parcel) const {
- return parcel->writeByteVector(*this);
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-status_t ParcelableCasPluginDescriptor::readFromParcel(const Parcel* /*parcel*/) {
- ALOGE("CAPluginDescriptor::readFromParcel() shouldn't be called");
- return INVALID_OPERATION;
-}
-
-status_t ParcelableCasPluginDescriptor::writeToParcel(Parcel* parcel) const {
- status_t err = parcel->writeInt32(mCASystemId);
- if (err != NO_ERROR) {
- return err;
- }
- return parcel->writeString16(mName);
-}
-
-} // namespace MediaCas
-///////////////////////////////////////////////////////////////////////////////
-
-namespace MediaDescrambler {
-
-DescrambleInfo::DescrambleInfo() {}
-
-DescrambleInfo::~DescrambleInfo() {}
-
-status_t DescrambleInfo::readFromParcel(const Parcel* parcel) {
- status_t err = parcel->readInt32((int32_t*)&dstType);
- if (err != OK) {
- return err;
- }
- if (dstType != kDestinationTypeNativeHandle
- && dstType != kDestinationTypeVmPointer) {
- return BAD_VALUE;
- }
-
- err = parcel->readInt32((int32_t*)&scramblingControl);
- if (err != OK) {
- return err;
- }
-
- err = parcel->readUint32((uint32_t*)&numSubSamples);
- if (err != OK) {
- return err;
- }
- if (numSubSamples > 0xffff) {
- return BAD_VALUE;
- }
-
- subSamples = new DescramblerPlugin::SubSample[numSubSamples];
- if (subSamples == NULL) {
- return NO_MEMORY;
- }
-
- for (size_t i = 0; i < numSubSamples; i++) {
- err = parcel->readUint32(&subSamples[i].mNumBytesOfClearData);
- if (err != OK) {
- return err;
- }
- err = parcel->readUint32(&subSamples[i].mNumBytesOfEncryptedData);
- if (err != OK) {
- return err;
- }
- }
-
- srcMem = interface_cast<IMemory>(parcel->readStrongBinder());
- if (srcMem == NULL) {
- return BAD_VALUE;
- }
-
- err = parcel->readInt32(&srcOffset);
- if (err != OK) {
- return err;
- }
-
- native_handle_t *nativeHandle = NULL;
- if (dstType == kDestinationTypeNativeHandle) {
- nativeHandle = parcel->readNativeHandle();
- dstPtr = static_cast<void *>(nativeHandle);
- } else {
- dstPtr = NULL;
- }
-
- err = parcel->readInt32(&dstOffset);
- if (err != OK) {
- return err;
- }
-
- return OK;
-}
-
-status_t DescrambleInfo::writeToParcel(Parcel* parcel) const {
- if (dstType != kDestinationTypeNativeHandle
- && dstType != kDestinationTypeVmPointer) {
- return BAD_VALUE;
- }
-
- status_t err = parcel->writeInt32((int32_t)dstType);
- if (err != OK) {
- return err;
- }
-
- err = parcel->writeInt32(scramblingControl);
- if (err != OK) {
- return err;
- }
-
- err = parcel->writeUint32(numSubSamples);
- if (err != OK) {
- return err;
- }
-
- for (size_t i = 0; i < numSubSamples; i++) {
- err = parcel->writeUint32(subSamples[i].mNumBytesOfClearData);
- if (err != OK) {
- return err;
- }
- err = parcel->writeUint32(subSamples[i].mNumBytesOfEncryptedData);
- if (err != OK) {
- return err;
- }
- }
-
- err = parcel->writeStrongBinder(IInterface::asBinder(srcMem));
- if (err != OK) {
- return err;
- }
-
- err = parcel->writeInt32(srcOffset);
- if (err != OK) {
- return err;
- }
-
- if (dstType == kDestinationTypeNativeHandle) {
- parcel->writeNativeHandle(static_cast<native_handle_t *>(dstPtr));
- }
-
- err = parcel->writeInt32(dstOffset);
- if (err != OK) {
- return err;
- }
-
- return OK;
-}
-
-} // namespace MediaDescrambler
-
-} // namespace media
-} // namespace android
-
diff --git a/drm/libmediadrm/aidl/android/media/ICas.aidl b/drm/libmediadrm/aidl/android/media/ICas.aidl
deleted file mode 100644
index 9746593..0000000
--- a/drm/libmediadrm/aidl/android/media/ICas.aidl
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * 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.
- */
-
-package android.media;
-
-import android.media.MediaCas;
-
-/** @hide */
-interface ICas {
- void setPrivateData(in byte[] pvtData);
- byte[] openSession();
- void closeSession(in byte[] sessionId);
- void setSessionPrivateData(in byte[] sessionId, in byte[] pvtData);
- void processEcm(in byte[] sessionId, in MediaCas.ParcelableCasData ecm);
- void processEmm(in MediaCas.ParcelableCasData emm);
- void sendEvent(int event, int arg, in @nullable byte[] eventData);
- void provision(String provisionString);
- void refreshEntitlements(int refreshType, in @nullable byte[] refreshData);
- void release();
-}
\ No newline at end of file
diff --git a/drm/libmediadrm/aidl/android/media/ICasListener.aidl b/drm/libmediadrm/aidl/android/media/ICasListener.aidl
deleted file mode 100644
index 01a5abc..0000000
--- a/drm/libmediadrm/aidl/android/media/ICasListener.aidl
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * 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.
- */
-
-package android.media;
-
-/** @hide */
-interface ICasListener {
- void onEvent(int event, int arg, in @nullable byte[] data);
-}
\ No newline at end of file
diff --git a/drm/libmediadrm/aidl/android/media/IDescrambler.aidl b/drm/libmediadrm/aidl/android/media/IDescrambler.aidl
deleted file mode 100644
index fdf99eb..0000000
--- a/drm/libmediadrm/aidl/android/media/IDescrambler.aidl
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * 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.
- */
-
-package android.media;
-
-import android.media.MediaDescrambler;
-
-/** @hide */
-interface IDescrambler {
- void setMediaCasSession(in byte[] sessionId);
- boolean requiresSecureDecoderComponent(String mime);
- int descramble(in MediaDescrambler.DescrambleInfo descrambleInfo);
- void release();
-}
\ No newline at end of file
diff --git a/drm/libmediadrm/aidl/android/media/IMediaCasService.aidl b/drm/libmediadrm/aidl/android/media/IMediaCasService.aidl
deleted file mode 100644
index 44f6825..0000000
--- a/drm/libmediadrm/aidl/android/media/IMediaCasService.aidl
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * 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.
- */
-
-package android.media;
-
-import android.media.IDescrambler;
-import android.media.ICas;
-import android.media.ICasListener;
-import android.media.MediaCas;
-
-/** @hide */
-interface IMediaCasService {
- MediaCas.ParcelableCasPluginDescriptor[] enumeratePlugins();
- boolean isSystemIdSupported(int CA_system_id);
- ICas createPlugin(int CA_system_id, ICasListener listener);
- boolean isDescramblerSupported(int CA_system_id);
- IDescrambler createDescrambler(int CA_system_id);
-}
-
diff --git a/drm/libmediadrm/aidl/android/media/MediaCas.aidl b/drm/libmediadrm/aidl/android/media/MediaCas.aidl
deleted file mode 100644
index cb8d0c6..0000000
--- a/drm/libmediadrm/aidl/android/media/MediaCas.aidl
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * 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.
- */
-
-package android.media;
-
-/** @hide */
-parcelable MediaCas.ParcelableCasPluginDescriptor cpp_header "media/MediaCasDefs.h";
-
-/** @hide */
-parcelable MediaCas.ParcelableCasData cpp_header "media/MediaCasDefs.h";
\ No newline at end of file
diff --git a/drm/libmediadrm/aidl/android/media/MediaDescrambler.aidl b/drm/libmediadrm/aidl/android/media/MediaDescrambler.aidl
deleted file mode 100644
index e789244..0000000
--- a/drm/libmediadrm/aidl/android/media/MediaDescrambler.aidl
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * 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.
- */
-
-package android.media;
-
-/** @hide */
-parcelable MediaDescrambler.DescrambleInfo cpp_header "media/MediaCasDefs.h";
\ No newline at end of file
diff --git a/drm/mediacas/plugins/clearkey/Android.mk b/drm/mediacas/plugins/clearkey/Android.mk
index 8fd866c..0c2b357 100644
--- a/drm/mediacas/plugins/clearkey/Android.mk
+++ b/drm/mediacas/plugins/clearkey/Android.mk
@@ -28,8 +28,7 @@
LOCAL_MODULE := libclearkeycasplugin
-#TODO: move this back to /vendor/lib after conversion to treble
-#LOCAL_PROPRIETARY_MODULE := true
+LOCAL_PROPRIETARY_MODULE := true
LOCAL_MODULE_RELATIVE_PATH := mediacas
LOCAL_SHARED_LIBRARIES := \
diff --git a/drm/mediacas/plugins/clearkey/ClearKeyCasPlugin.cpp b/drm/mediacas/plugins/clearkey/ClearKeyCasPlugin.cpp
index 4ed5fce..e27631f 100644
--- a/drm/mediacas/plugins/clearkey/ClearKeyCasPlugin.cpp
+++ b/drm/mediacas/plugins/clearkey/ClearKeyCasPlugin.cpp
@@ -121,7 +121,7 @@
sp<ClearKeyCasSession> session =
ClearKeySessionLibrary::get()->findSession(sessionId);
if (session == NULL) {
- return ERROR_DRM_SESSION_NOT_OPENED;
+ return ERROR_CAS_SESSION_NOT_OPENED;
}
ClearKeySessionLibrary::get()->destroySession(sessionId);
@@ -135,7 +135,7 @@
sp<ClearKeyCasSession> session =
ClearKeySessionLibrary::get()->findSession(sessionId);
if (session == NULL) {
- return ERROR_DRM_SESSION_NOT_OPENED;
+ return ERROR_CAS_SESSION_NOT_OPENED;
}
return OK;
}
@@ -146,7 +146,7 @@
sp<ClearKeyCasSession> session =
ClearKeySessionLibrary::get()->findSession(sessionId);
if (session == NULL) {
- return ERROR_DRM_SESSION_NOT_OPENED;
+ return ERROR_CAS_SESSION_NOT_OPENED;
}
Mutex::Autolock lock(mKeyFetcherLock);
@@ -293,7 +293,7 @@
status_t ClearKeyCasSession::updateECM(
KeyFetcher *keyFetcher, void *ecm, size_t size) {
if (keyFetcher == nullptr) {
- return ERROR_DRM_NOT_PROVISIONED;
+ return ERROR_CAS_NOT_PROVISIONED;
}
if (size < kEcmHeaderLength) {
@@ -344,7 +344,7 @@
size_t numSubSamples, const DescramblerPlugin::SubSample *subSamples,
const void *srcPtr, void *dstPtr, AString * /* errorDetailMsg */) {
if (secure) {
- return ERROR_DRM_CANNOT_HANDLE;
+ return ERROR_CAS_CANNOT_HANDLE;
}
AES_KEY contentKey;
@@ -356,7 +356,7 @@
int32_t keyIndex = (scramblingControl & 1);
if (!mKeyInfo[keyIndex].valid) {
ALOGE("decrypt: key %d is invalid", keyIndex);
- return ERROR_DRM_DECRYPT;
+ return ERROR_CAS_DECRYPT;
}
contentKey = mKeyInfo[keyIndex].contentKey;
}
@@ -420,7 +420,7 @@
if (session == NULL) {
ALOGE("ClearKeyDescramblerPlugin: session not found");
- return ERROR_DRM_SESSION_NOT_OPENED;
+ return ERROR_CAS_SESSION_NOT_OPENED;
}
mCASSession = session;
@@ -446,7 +446,7 @@
if (mCASSession == NULL) {
ALOGE("Uninitialized CAS session!");
- return ERROR_DRM_DECRYPT_UNIT_NOT_INITIALIZED;
+ return ERROR_CAS_DECRYPT_UNIT_NOT_INITIALIZED;
}
return mCASSession->decrypt(
diff --git a/drm/mediacas/plugins/clearkey/JsonAssetLoader.cpp b/drm/mediacas/plugins/clearkey/JsonAssetLoader.cpp
index 9cd77e9..6e1004c 100644
--- a/drm/mediacas/plugins/clearkey/JsonAssetLoader.cpp
+++ b/drm/mediacas/plugins/clearkey/JsonAssetLoader.cpp
@@ -48,24 +48,24 @@
* Extract a clear key asset from a JSON string.
*
* Returns OK if a clear key asset is extracted successfully,
- * or ERROR_DRM_NO_LICENSE if the string doesn't contain a valid
+ * or ERROR_CAS_NO_LICENSE if the string doesn't contain a valid
* clear key asset.
*/
status_t JsonAssetLoader::extractAssetFromString(
const String8& jsonAssetString, Asset *asset) {
if (!parseJsonAssetString(jsonAssetString, &mJsonObjects)) {
- return ERROR_DRM_NO_LICENSE;
+ return ERROR_CAS_NO_LICENSE;
}
if (mJsonObjects.size() < 1) {
- return ERROR_DRM_NO_LICENSE;
+ return ERROR_CAS_NO_LICENSE;
}
if (!parseJsonObject(mJsonObjects[0], &mTokens))
- return ERROR_DRM_NO_LICENSE;
+ return ERROR_CAS_NO_LICENSE;
if (!findKey(mJsonObjects[0], asset)) {
- return ERROR_DRM_NO_LICENSE;
+ return ERROR_CAS_NO_LICENSE;
}
return OK;
}
diff --git a/drm/mediacas/plugins/clearkey/ecm_generator.h b/drm/mediacas/plugins/clearkey/ecm_generator.h
index 2ef06c4..5fbdea5 100644
--- a/drm/mediacas/plugins/clearkey/ecm_generator.h
+++ b/drm/mediacas/plugins/clearkey/ecm_generator.h
@@ -29,7 +29,7 @@
namespace android {
namespace clearkeycas {
enum {
- CLEARKEY_STATUS_BASE = ERROR_DRM_VENDOR_MAX,
+ CLEARKEY_STATUS_BASE = ERROR_CAS_VENDOR_MAX,
CLEARKEY_STATUS_INVALIDASSETID = CLEARKEY_STATUS_BASE - 1,
CLEARKEY_STATUS_INVALIDSYSTEMID = CLEARKEY_STATUS_BASE - 2,
CLEARKEY_STATUS_INVALID_PARAMETER = CLEARKEY_STATUS_BASE - 3,
diff --git a/drm/mediacas/plugins/clearkey/tests/Android.mk b/drm/mediacas/plugins/clearkey/tests/Android.mk
index cbf7be7..5418c1d 100644
--- a/drm/mediacas/plugins/clearkey/tests/Android.mk
+++ b/drm/mediacas/plugins/clearkey/tests/Android.mk
@@ -26,7 +26,7 @@
# the plugin is not in standard library search path. Without this .so
# loading fails at run-time (linking is okay).
LOCAL_LDFLAGS := \
- -Wl,--rpath,\$${ORIGIN}/../../../system/lib/mediacas -Wl,--enable-new-dtags
+ -Wl,--rpath,\$${ORIGIN}/../../../system/vendor/lib/mediacas -Wl,--enable-new-dtags
LOCAL_SHARED_LIBRARIES := \
libutils libclearkeycasplugin libstagefright_foundation libprotobuf-cpp-lite liblog
diff --git a/include/media/CasImpl.h b/include/media/CasImpl.h
deleted file mode 100644
index 726f1ce..0000000
--- a/include/media/CasImpl.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * 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 CAS_IMPL_H_
-#define CAS_IMPL_H_
-
-#include <media/stagefright/foundation/ABase.h>
-#include <android/media/BnCas.h>
-
-namespace android {
-namespace media {
-class ICasListener;
-}
-using namespace media;
-using namespace MediaCas;
-using binder::Status;
-struct CasPlugin;
-class SharedLibrary;
-
-class CasImpl : public BnCas {
-public:
- CasImpl(const sp<ICasListener> &listener);
- virtual ~CasImpl();
-
- static void OnEvent(
- void *appData,
- int32_t event,
- int32_t arg,
- uint8_t *data,
- size_t size);
-
- void init(const sp<SharedLibrary>& library, CasPlugin *plugin);
- void onEvent(
- int32_t event,
- int32_t arg,
- uint8_t *data,
- size_t size);
-
- // ICas inherits
-
- virtual Status setPrivateData(
- const CasData& pvtData) override;
-
- virtual Status openSession(CasSessionId* _aidl_return) override;
-
- virtual Status closeSession(const CasSessionId& sessionId) override;
-
- virtual Status setSessionPrivateData(
- const CasSessionId& sessionId,
- const CasData& pvtData) override;
-
- virtual Status processEcm(
- const CasSessionId& sessionId, const ParcelableCasData& ecm) override;
-
- virtual Status processEmm(const ParcelableCasData& emm) override;
-
- virtual Status sendEvent(
- int32_t event, int32_t arg, const ::std::unique_ptr<CasData> &eventData) override;
-
- virtual Status provision(const String16& provisionString) override;
-
- virtual Status refreshEntitlements(
- int32_t refreshType, const ::std::unique_ptr<CasData> &refreshData) override;
-
- virtual Status release() override;
-
-private:
- struct PluginHolder;
- sp<SharedLibrary> mLibrary;
- sp<PluginHolder> mPluginHolder;
- sp<ICasListener> mListener;
-
- DISALLOW_EVIL_CONSTRUCTORS(CasImpl);
-};
-
-} // namespace android
-
-#endif // CAS_IMPL_H_
diff --git a/include/media/DescramblerImpl.h b/include/media/DescramblerImpl.h
deleted file mode 100644
index 9f212ac..0000000
--- a/include/media/DescramblerImpl.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * 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 DESCRAMBLER_IMPL_H_
-#define DESCRAMBLER_IMPL_H_
-
-#include <media/stagefright/foundation/ABase.h>
-#include <android/media/BnDescrambler.h>
-
-namespace android {
-using namespace media;
-using namespace MediaDescrambler;
-using binder::Status;
-struct DescramblerPlugin;
-class SharedLibrary;
-
-class DescramblerImpl : public BnDescrambler {
-public:
- DescramblerImpl(const sp<SharedLibrary>& library, DescramblerPlugin *plugin);
- virtual ~DescramblerImpl();
-
- virtual Status setMediaCasSession(
- const CasSessionId& sessionId) override;
-
- virtual Status requiresSecureDecoderComponent(
- const String16& mime, bool *result) override;
-
- virtual Status descramble(
- const DescrambleInfo& descrambleInfo, int32_t *result) override;
-
- virtual Status release() override;
-
-private:
- sp<SharedLibrary> mLibrary;
- DescramblerPlugin *mPlugin;
-
- DISALLOW_EVIL_CONSTRUCTORS(DescramblerImpl);
-};
-
-} // namespace android
-
-#endif // DESCRAMBLER_IMPL_H_
diff --git a/include/media/MediaCasDefs.h b/include/media/MediaCasDefs.h
deleted file mode 100644
index 8c5a967..0000000
--- a/include/media/MediaCasDefs.h
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * 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 MEDIA_CAS_DEFS_H_
-#define MEDIA_CAS_DEFS_H_
-
-#include <binder/Parcel.h>
-#include <media/cas/CasAPI.h>
-#include <media/cas/DescramblerAPI.h>
-#include <media/stagefright/foundation/ABase.h>
-
-namespace android {
-class IMemory;
-namespace media {
-
-namespace MediaCas {
-class ParcelableCasData : public CasData,
- public Parcelable {
-public:
- ParcelableCasData() {}
- ParcelableCasData(const uint8_t *data, size_t size) :
- CasData(data, data + size) {}
- virtual ~ParcelableCasData() {}
- status_t readFromParcel(const Parcel* parcel) override;
- status_t writeToParcel(Parcel* parcel) const override;
-
-private:
- DISALLOW_EVIL_CONSTRUCTORS(ParcelableCasData);
-};
-
-class ParcelableCasPluginDescriptor : public Parcelable {
-public:
- ParcelableCasPluginDescriptor(int32_t CA_system_id, const char *name)
- : mCASystemId(CA_system_id), mName(name) {}
-
- ParcelableCasPluginDescriptor() : mCASystemId(0) {}
-
- ParcelableCasPluginDescriptor(ParcelableCasPluginDescriptor&& desc) = default;
-
- virtual ~ParcelableCasPluginDescriptor() {}
-
- status_t readFromParcel(const Parcel* parcel) override;
- status_t writeToParcel(Parcel* parcel) const override;
-
-private:
- int32_t mCASystemId;
- String16 mName;
- DISALLOW_EVIL_CONSTRUCTORS(ParcelableCasPluginDescriptor);
-};
-}
-
-namespace MediaDescrambler {
-class DescrambleInfo : public Parcelable {
-public:
- enum DestinationType {
- kDestinationTypeVmPointer, // non-secure
- kDestinationTypeNativeHandle // secure
- };
-
- DestinationType dstType;
- DescramblerPlugin::ScramblingControl scramblingControl;
- size_t numSubSamples;
- DescramblerPlugin::SubSample *subSamples;
- sp<IMemory> srcMem;
- int32_t srcOffset;
- void *dstPtr;
- int32_t dstOffset;
-
- DescrambleInfo();
- virtual ~DescrambleInfo();
- status_t readFromParcel(const Parcel* parcel) override;
- status_t writeToParcel(Parcel* parcel) const override;
-
-private:
-
- DISALLOW_EVIL_CONSTRUCTORS(DescrambleInfo);
-};
-}
-
-} // namespace media
-} // namespace android
-
-
-#endif // MEDIA_CAS_DEFS_H_
diff --git a/media/libmedia/IMediaExtractor.cpp b/media/libmedia/IMediaExtractor.cpp
index f08fabb..19b00f3 100644
--- a/media/libmedia/IMediaExtractor.cpp
+++ b/media/libmedia/IMediaExtractor.cpp
@@ -21,7 +21,6 @@
#include <stdint.h>
#include <sys/types.h>
-#include <android/media/ICas.h>
#include <binder/IPCThreadState.h>
#include <binder/Parcel.h>
#include <media/IMediaExtractor.h>
@@ -117,12 +116,12 @@
return NULL;
}
- virtual status_t setMediaCas(const sp<ICas> & cas) {
+ virtual status_t setMediaCas(const HInterfaceToken &casToken) {
ALOGV("setMediaCas");
Parcel data, reply;
data.writeInterfaceToken(BpMediaExtractor::getInterfaceDescriptor());
- data.writeStrongBinder(IInterface::asBinder(cas));
+ data.writeByteVector(casToken);
status_t err = remote()->transact(SETMEDIACAS, data, &reply);
if (err != NO_ERROR) {
@@ -206,15 +205,14 @@
ALOGV("setMediaCas");
CHECK_INTERFACE(IMediaExtractor, data, reply);
- sp<IBinder> casBinder;
- status_t err = data.readNullableStrongBinder(&casBinder);
+ HInterfaceToken casToken;
+ status_t err = data.readByteVector(&casToken);
if (err != NO_ERROR) {
- ALOGE("Error reading cas from parcel");
+ ALOGE("Error reading casToken from parcel");
return err;
}
- sp<ICas> cas = interface_cast<ICas>(casBinder);
- reply->writeInt32(setMediaCas(cas));
+ reply->writeInt32(setMediaCas(casToken));
return OK;
}
default:
diff --git a/media/libmedia/include/media/IMediaExtractor.h b/media/libmedia/include/media/IMediaExtractor.h
index ab40f53..1e13b65 100644
--- a/media/libmedia/include/media/IMediaExtractor.h
+++ b/media/libmedia/include/media/IMediaExtractor.h
@@ -20,14 +20,12 @@
#include <media/IMediaSource.h>
#include <media/stagefright/DataSource.h>
+#include <vector>
namespace android {
class MetaData;
-namespace media {
-class ICas;
-};
-using namespace media;
+typedef std::vector<uint8_t> HInterfaceToken;
class IMediaExtractor : public IInterface {
public:
@@ -65,7 +63,7 @@
// for DRM
virtual char* getDrmTrackInfo(size_t trackID, int *len) = 0;
- virtual status_t setMediaCas(const sp<ICas> &cas) = 0;
+ virtual status_t setMediaCas(const HInterfaceToken &casToken) = 0;
virtual void setUID(uid_t uid) = 0;
diff --git a/media/libstagefright/ACodecBufferChannel.cpp b/media/libstagefright/ACodecBufferChannel.cpp
index 0d9696f..3c7ae3e 100644
--- a/media/libstagefright/ACodecBufferChannel.cpp
+++ b/media/libstagefright/ACodecBufferChannel.cpp
@@ -20,7 +20,7 @@
#include <numeric>
-#include <android/media/IDescrambler.h>
+#include <android/hardware/cas/native/1.0/IDescrambler.h>
#include <binder/MemoryDealer.h>
#include <media/openmax/OMX_Core.h>
#include <media/stagefright/foundation/AMessage.h>
@@ -34,8 +34,11 @@
#include "include/SharedMemoryBuffer.h"
namespace android {
-using binder::Status;
-using MediaDescrambler::DescrambleInfo;
+using hardware::hidl_handle;
+using hardware::hidl_string;
+using hardware::hidl_vec;
+using namespace hardware::cas::V1_0;
+using namespace hardware::cas::native::V1_0;
using BufferInfo = ACodecBufferChannel::BufferInfo;
using BufferInfoIterator = std::vector<const BufferInfo>::const_iterator;
@@ -114,74 +117,97 @@
return -ENOENT;
}
- ICrypto::DestinationBuffer destination;
+ native_handle_t *secureHandle = NULL;
if (secure) {
sp<SecureBuffer> secureData =
static_cast<SecureBuffer *>(it->mCodecBuffer.get());
- destination.mType = secureData->getDestinationType();
- if (destination.mType != ICrypto::kDestinationTypeNativeHandle) {
+ if (secureData->getDestinationType() != ICrypto::kDestinationTypeNativeHandle) {
return BAD_VALUE;
}
- destination.mHandle =
- static_cast<native_handle_t *>(secureData->getDestinationPointer());
- } else {
- destination.mType = ICrypto::kDestinationTypeSharedMemory;
- destination.mSharedMemory = mDecryptDestination;
+ secureHandle = static_cast<native_handle_t *>(secureData->getDestinationPointer());
}
-
- ICrypto::SourceBuffer source;
- source.mSharedMemory = it->mSharedEncryptedBuffer;
- source.mHeapSeqNum = mHeapSeqNum;
-
ssize_t result = -1;
if (mCrypto != NULL) {
+ ICrypto::DestinationBuffer destination;
+ if (secure) {
+ destination.mType = ICrypto::kDestinationTypeNativeHandle;
+ destination.mHandle = secureHandle;
+ } else {
+ destination.mType = ICrypto::kDestinationTypeSharedMemory;
+ destination.mSharedMemory = mDecryptDestination;
+ }
+
+ ICrypto::SourceBuffer source;
+ source.mSharedMemory = it->mSharedEncryptedBuffer;
+ source.mHeapSeqNum = mHeapSeqNum;
+
result = mCrypto->decrypt(key, iv, mode, pattern,
source, it->mClientBuffer->offset(),
subSamples, numSubSamples, destination, errorDetailMsg);
- } else {
- DescrambleInfo descrambleInfo;
- descrambleInfo.dstType = destination.mType ==
- ICrypto::kDestinationTypeSharedMemory ?
- DescrambleInfo::kDestinationTypeVmPointer :
- DescrambleInfo::kDestinationTypeNativeHandle;
- descrambleInfo.scramblingControl = key != NULL ?
- (DescramblerPlugin::ScramblingControl)key[0] :
- DescramblerPlugin::kScrambling_Unscrambled;
- descrambleInfo.numSubSamples = numSubSamples;
- descrambleInfo.subSamples = (DescramblerPlugin::SubSample *)subSamples;
- descrambleInfo.srcMem = it->mSharedEncryptedBuffer;
- descrambleInfo.srcOffset = 0;
- descrambleInfo.dstPtr = NULL;
- descrambleInfo.dstOffset = 0;
-
- int32_t descrambleResult = -1;
- Status status = mDescrambler->descramble(descrambleInfo, &descrambleResult);
-
- if (status.isOk()) {
- result = descrambleResult;
- }
if (result < 0) {
- ALOGE("descramble failed, exceptionCode=%d, err=%d, result=%zd",
- status.exceptionCode(), status.transactionError(), result);
- } else {
- ALOGV("descramble succeeded, result=%zd", result);
+ return result;
}
- if (result > 0 && destination.mType == ICrypto::kDestinationTypeSharedMemory) {
- memcpy(destination.mSharedMemory->pointer(),
+ if (destination.mType == ICrypto::kDestinationTypeSharedMemory) {
+ memcpy(it->mCodecBuffer->base(), destination.mSharedMemory->pointer(), result);
+ }
+ } else {
+ // Here we cast CryptoPlugin::SubSample to hardware::cas::native::V1_0::SubSample
+ // directly, the structure definitions should match as checked in DescramblerImpl.cpp.
+ hidl_vec<SubSample> hidlSubSamples;
+ hidlSubSamples.setToExternal((SubSample *)subSamples, numSubSamples, false /*own*/);
+
+ ssize_t offset;
+ size_t size;
+ it->mSharedEncryptedBuffer->getMemory(&offset, &size);
+ hardware::cas::native::V1_0::SharedBuffer srcBuffer = {
+ .heapBase = mHidlMemory,
+ .offset = (uint64_t) offset,
+ .size = size
+ };
+
+ DestinationBuffer dstBuffer;
+ if (secure) {
+ dstBuffer.type = BufferType::NATIVE_HANDLE;
+ dstBuffer.secureMemory = hidl_handle(secureHandle);
+ } else {
+ dstBuffer.type = BufferType::SHARED_MEMORY;
+ dstBuffer.nonsecureMemory = srcBuffer;
+ }
+
+ Status status = Status::OK;
+ hidl_string detailedError;
+
+ auto returnVoid = mDescrambler->descramble(
+ key != NULL ? (ScramblingControl)key[0] : ScramblingControl::UNSCRAMBLED,
+ hidlSubSamples,
+ srcBuffer,
+ 0,
+ dstBuffer,
+ 0,
+ [&status, &result, &detailedError] (
+ Status _status, uint32_t _bytesWritten,
+ const hidl_string& _detailedError) {
+ status = _status;
+ result = (ssize_t)_bytesWritten;
+ detailedError = _detailedError;
+ });
+
+ if (!returnVoid.isOk() || status != Status::OK || result < 0) {
+ ALOGE("descramble failed, trans=%s, status=%d, result=%zd",
+ returnVoid.description().c_str(), status, result);
+ return UNKNOWN_ERROR;
+ }
+
+ ALOGV("descramble succeeded, %zd bytes", result);
+
+ if (dstBuffer.type == BufferType::SHARED_MEMORY) {
+ memcpy(it->mCodecBuffer->base(),
(uint8_t*)it->mSharedEncryptedBuffer->pointer(), result);
}
}
- if (result < 0) {
- return result;
- }
-
- if (destination.mType == ICrypto::kDestinationTypeSharedMemory) {
- memcpy(it->mCodecBuffer->base(), destination.mSharedMemory->pointer(), result);
- }
-
it->mCodecBuffer->setRange(0, result);
// Copy metadata from client to codec buffer.
@@ -275,10 +301,21 @@
int32_t seqNum = mCrypto->setHeap(dealer->getMemoryHeap());
if (seqNum >= 0) {
mHeapSeqNum = seqNum;
- ALOGD("setHeap returned mHeapSeqNum=%d", mHeapSeqNum);
+ ALOGV("setHeap returned mHeapSeqNum=%d", mHeapSeqNum);
} else {
mHeapSeqNum = -1;
- ALOGD("setHeap failed, setting mHeapSeqNum=-1");
+ ALOGE("setHeap failed, setting mHeapSeqNum=-1");
+ }
+ } else if (mDescrambler != nullptr) {
+ sp<IMemoryHeap> heap = dealer->getMemoryHeap();
+ native_handle_t* nativeHandle = native_handle_create(1, 0);
+ if (nativeHandle != nullptr) {
+ int fd = heap->getHeapID();
+ nativeHandle->data[0] = fd;
+ mHidlMemory = hidl_memory("ashmem", hidl_handle(nativeHandle), heap->getSize());
+ ALOGV("created hidl_memory for descrambler");
+ } else {
+ ALOGE("failed to create hidl_memory for descrambler");
}
}
return dealer;
diff --git a/media/libstagefright/Android.bp b/media/libstagefright/Android.bp
index 5fcb1fe..45a8d94 100644
--- a/media/libstagefright/Android.bp
+++ b/media/libstagefright/Android.bp
@@ -17,6 +17,7 @@
"AudioPlayer.cpp",
"AudioSource.cpp",
"BufferImpl.cpp",
+ "CodecBase.cpp",
"CallbackDataSource.cpp",
"CameraSource.cpp",
"CameraSourceTimeLapse.cpp",
@@ -105,6 +106,9 @@
"libhidlmemory",
"android.hidl.allocator@1.0",
"android.hidl.memory@1.0",
+ "android.hidl.token@1.0-utils",
+ "android.hardware.cas@1.0",
+ "android.hardware.cas.native@1.0",
"android.hardware.media.omx@1.0",
"libstagefright_xmlparser@1.0",
],
diff --git a/media/libstagefright/CodecBase.cpp b/media/libstagefright/CodecBase.cpp
new file mode 100644
index 0000000..d0610b2
--- /dev/null
+++ b/media/libstagefright/CodecBase.cpp
@@ -0,0 +1,35 @@
+/*
+ * Copyright 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.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "CodecBase"
+
+#include <android/hardware/cas/native/1.0/IDescrambler.h>
+#include <media/ICrypto.h>
+#include <media/stagefright/CodecBase.h>
+#include <utils/Log.h>
+
+namespace android {
+
+void BufferChannelBase::setCrypto(const sp<ICrypto> &crypto) {
+ mCrypto = crypto;
+}
+
+void BufferChannelBase::setDescrambler(const sp<IDescrambler> &descrambler) {
+ mDescrambler = descrambler;
+}
+
+} // namespace android
diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp
index bd71632..98d101a 100644
--- a/media/libstagefright/MediaCodec.cpp
+++ b/media/libstagefright/MediaCodec.cpp
@@ -23,7 +23,8 @@
#include "include/SharedMemoryBuffer.h"
#include "include/SoftwareRenderer.h"
-#include <android/media/IDescrambler.h>
+#include <android/hardware/cas/native/1.0/IDescrambler.h>
+
#include <binder/IMemory.h>
#include <binder/IPCThreadState.h>
#include <binder/IServiceManager.h>
diff --git a/media/libstagefright/NuMediaExtractor.cpp b/media/libstagefright/NuMediaExtractor.cpp
index 51f1ba3..640cb82 100644
--- a/media/libstagefright/NuMediaExtractor.cpp
+++ b/media/libstagefright/NuMediaExtractor.cpp
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-//#define LOG_NDEBUG 0
+#define LOG_NDEBUG 0
#define LOG_TAG "NuMediaExtractor"
#include <utils/Log.h>
@@ -35,7 +35,6 @@
#include <media/stagefright/MediaSource.h>
#include <media/stagefright/MetaData.h>
#include <media/stagefright/Utils.h>
-#include <android/media/ICas.h>
namespace android {
@@ -83,8 +82,8 @@
return ERROR_UNSUPPORTED;
}
- if (mCas != NULL) {
- mImpl->setMediaCas(mCas);
+ if (!mCasToken.empty()) {
+ mImpl->setMediaCas(mCasToken);
}
status_t err = updateDurationAndBitrate();
@@ -119,8 +118,8 @@
return ERROR_UNSUPPORTED;
}
- if (mCas != NULL) {
- mImpl->setMediaCas(mCas);
+ if (!mCasToken.empty()) {
+ mImpl->setMediaCas(mCasToken);
}
err = updateDurationAndBitrate();
@@ -149,8 +148,8 @@
return ERROR_UNSUPPORTED;
}
- if (mCas != NULL) {
- mImpl->setMediaCas(mCas);
+ if (!mCasToken.empty()) {
+ mImpl->setMediaCas(mCasToken);
}
err = updateDurationAndBitrate();
@@ -161,24 +160,36 @@
return err;
}
-status_t NuMediaExtractor::setMediaCas(const sp<ICas> &cas) {
- ALOGV("setMediaCas: cas=%p", cas.get());
+static String8 arrayToString(const std::vector<uint8_t> &array) {
+ String8 result;
+ for (size_t i = 0; i < array.size(); i++) {
+ result.appendFormat("%02x ", array[i]);
+ }
+ if (result.isEmpty()) {
+ result.append("(null)");
+ }
+ return result;
+}
+
+status_t NuMediaExtractor::setMediaCas(const HInterfaceToken &casToken) {
+ ALOGV("setMediaCas: casToken={%s}", arrayToString(casToken).c_str());
Mutex::Autolock autoLock(mLock);
- if (cas == NULL) {
+ if (casToken.empty()) {
return BAD_VALUE;
}
+ mCasToken = casToken;
+
if (mImpl != NULL) {
- mImpl->setMediaCas(cas);
+ mImpl->setMediaCas(casToken);
status_t err = updateDurationAndBitrate();
if (err != OK) {
return err;
}
}
- mCas = cas;
return OK;
}
diff --git a/media/libstagefright/include/ACodecBufferChannel.h b/media/libstagefright/include/ACodecBufferChannel.h
index 0da2e81..f253a52 100644
--- a/media/libstagefright/include/ACodecBufferChannel.h
+++ b/media/libstagefright/include/ACodecBufferChannel.h
@@ -30,6 +30,8 @@
namespace android {
+using hardware::hidl_memory;
+
/**
* BufferChannelBase implementation for ACodec.
*/
@@ -117,6 +119,7 @@
sp<MemoryDealer> mDealer;
sp<IMemory> mDecryptDestination;
int32_t mHeapSeqNum;
+ hidl_memory mHidlMemory;
// These should only be accessed via std::atomic_* functions.
//
diff --git a/media/libstagefright/include/MPEG2TSExtractor.h b/media/libstagefright/include/MPEG2TSExtractor.h
index 2a75298f..ac93b5e 100644
--- a/media/libstagefright/include/MPEG2TSExtractor.h
+++ b/media/libstagefright/include/MPEG2TSExtractor.h
@@ -45,7 +45,7 @@
virtual sp<MetaData> getMetaData();
- virtual status_t setMediaCas(const sp<ICas> &cas) override;
+ virtual status_t setMediaCas(const HInterfaceToken &casToken) override;
virtual uint32_t flags() const;
virtual const char * name() { return "MPEG2TSExtractor"; }
diff --git a/media/libstagefright/include/media/stagefright/CodecBase.h b/media/libstagefright/include/media/stagefright/CodecBase.h
index 0dd77ba..6245ccb 100644
--- a/media/libstagefright/include/media/stagefright/CodecBase.h
+++ b/media/libstagefright/include/media/stagefright/CodecBase.h
@@ -24,27 +24,31 @@
#define STRINGIFY_ENUMS
-#include <media/ICrypto.h>
+#include <media/hardware/CryptoAPI.h>
+#include <media/hardware/HardwareAPI.h>
#include <media/IOMX.h>
#include <media/MediaCodecInfo.h>
-#include <media/stagefright/MediaErrors.h>
#include <media/stagefright/foundation/AHandler.h>
#include <media/stagefright/foundation/ColorUtils.h>
-#include <media/hardware/HardwareAPI.h>
-
+#include <media/stagefright/MediaErrors.h>
+#include <system/graphics.h>
#include <utils/NativeHandle.h>
-#include <system/graphics.h>
-#include <android/media/IDescrambler.h>
-
namespace android {
-using namespace media;
class BufferChannelBase;
struct BufferProducerWrapper;
class MediaCodecBuffer;
struct PersistentSurface;
struct RenderedFrameInfo;
class Surface;
+struct ICrypto;
+namespace hardware {
+namespace cas {
+namespace native {
+namespace V1_0 {
+struct IDescrambler;
+}}}}
+using hardware::cas::native::V1_0::IDescrambler;
struct CodecBase : public AHandler, /* static */ ColorUtils {
/**
@@ -256,13 +260,9 @@
mCallback = std::move(callback);
}
- inline void setCrypto(const sp<ICrypto> &crypto) {
- mCrypto = crypto;
- }
+ void setCrypto(const sp<ICrypto> &crypto);
- inline void setDescrambler(const sp<IDescrambler> &descrambler) {
- mDescrambler = descrambler;
- }
+ void setDescrambler(const sp<IDescrambler> &descrambler);
/**
* Queue an input buffer into the buffer channel.
diff --git a/media/libstagefright/include/media/stagefright/MediaCodec.h b/media/libstagefright/include/media/stagefright/MediaCodec.h
index 4140266..209fe12 100644
--- a/media/libstagefright/include/media/stagefright/MediaCodec.h
+++ b/media/libstagefright/include/media/stagefright/MediaCodec.h
@@ -47,10 +47,13 @@
struct PersistentSurface;
class SoftwareRenderer;
class Surface;
-namespace media {
-class IDescrambler;
-};
-using namespace media;
+namespace hardware {
+namespace cas {
+namespace native {
+namespace V1_0 {
+struct IDescrambler;
+}}}}
+using hardware::cas::native::V1_0::IDescrambler;
struct MediaCodec : public AHandler {
enum ConfigureFlags {
diff --git a/media/libstagefright/include/media/stagefright/MediaErrors.h b/media/libstagefright/include/media/stagefright/MediaErrors.h
index 2e663ec..6a5c6b6 100644
--- a/media/libstagefright/include/media/stagefright/MediaErrors.h
+++ b/media/libstagefright/include/media/stagefright/MediaErrors.h
@@ -79,6 +79,26 @@
HEARTBEAT_ERROR_BASE = -3000,
ERROR_HEARTBEAT_TERMINATE_REQUESTED = HEARTBEAT_ERROR_BASE,
+ // CAS-related error codes
+ CAS_ERROR_BASE = -4000,
+
+ ERROR_CAS_UNKNOWN = CAS_ERROR_BASE,
+ ERROR_CAS_NO_LICENSE = CAS_ERROR_BASE - 1,
+ ERROR_CAS_LICENSE_EXPIRED = CAS_ERROR_BASE - 2,
+ ERROR_CAS_SESSION_NOT_OPENED = CAS_ERROR_BASE - 3,
+ ERROR_CAS_DECRYPT_UNIT_NOT_INITIALIZED = CAS_ERROR_BASE - 4,
+ ERROR_CAS_DECRYPT = CAS_ERROR_BASE - 5,
+ ERROR_CAS_CANNOT_HANDLE = CAS_ERROR_BASE - 6,
+ ERROR_CAS_TAMPER_DETECTED = CAS_ERROR_BASE - 7,
+ ERROR_CAS_NOT_PROVISIONED = CAS_ERROR_BASE - 8,
+ ERROR_CAS_DEVICE_REVOKED = CAS_ERROR_BASE - 9,
+ ERROR_CAS_RESOURCE_BUSY = CAS_ERROR_BASE - 10,
+ ERROR_CAS_INSUFFICIENT_OUTPUT_PROTECTION = CAS_ERROR_BASE - 11,
+ ERROR_CAS_LAST_USED_ERRORCODE = CAS_ERROR_BASE - 11,
+
+ ERROR_CAS_VENDOR_MAX = CAS_ERROR_BASE - 500,
+ ERROR_CAS_VENDOR_MIN = CAS_ERROR_BASE - 999,
+
// NDK Error codes
// frameworks/av/include/ndk/NdkMediaError.h
// from -10000 (0xFFFFD8F0 - 0xFFFFD8EC)
diff --git a/media/libstagefright/include/media/stagefright/MediaExtractor.h b/media/libstagefright/include/media/stagefright/MediaExtractor.h
index a856b2b..f12160b 100644
--- a/media/libstagefright/include/media/stagefright/MediaExtractor.h
+++ b/media/libstagefright/include/media/stagefright/MediaExtractor.h
@@ -23,10 +23,6 @@
#include <media/MediaAnalyticsItem.h>
namespace android {
-namespace media {
-class ICas;
-};
-using namespace media;
class DataSource;
struct MediaSource;
class MetaData;
@@ -70,7 +66,7 @@
}
virtual void setUID(uid_t /*uid*/) {
}
- virtual status_t setMediaCas(const sp<ICas>& /*cas*/) override {
+ virtual status_t setMediaCas(const HInterfaceToken &/*casToken*/) override {
return INVALID_OPERATION;
}
diff --git a/media/libstagefright/include/media/stagefright/NuMediaExtractor.h b/media/libstagefright/include/media/stagefright/NuMediaExtractor.h
index 3e3cc17..6a93bd5 100644
--- a/media/libstagefright/include/media/stagefright/NuMediaExtractor.h
+++ b/media/libstagefright/include/media/stagefright/NuMediaExtractor.h
@@ -28,10 +28,6 @@
#include <utils/Vector.h>
namespace android {
-namespace media {
-class ICas;
-}
-using namespace media;
struct ABuffer;
struct AMessage;
@@ -64,7 +60,7 @@
status_t setDataSource(const sp<DataSource> &datasource);
- status_t setMediaCas(const sp<ICas> &cas);
+ status_t setMediaCas(const HInterfaceToken &casToken);
size_t countTracks() const;
status_t getTrackFormat(size_t index, sp<AMessage> *format, uint32_t flags = 0) const;
@@ -115,7 +111,7 @@
sp<DataSource> mDataSource;
sp<IMediaExtractor> mImpl;
- sp<ICas> mCas;
+ HInterfaceToken mCasToken;
Vector<TrackInfo> mSelectedTracks;
int64_t mTotalBitrate; // in bits/sec
diff --git a/media/libstagefright/mpeg2ts/ATSParser.cpp b/media/libstagefright/mpeg2ts/ATSParser.cpp
index 31edb21..a256a4d 100644
--- a/media/libstagefright/mpeg2ts/ATSParser.cpp
+++ b/media/libstagefright/mpeg2ts/ATSParser.cpp
@@ -23,8 +23,8 @@
#include "ESQueue.h"
#include "include/avc_utils.h"
-#include <android/media/IDescrambler.h>
-#include <binder/MemoryDealer.h>
+#include <android/hardware/cas/native/1.0/IDescrambler.h>
+#include <cutils/native_handle.h>
#include <media/stagefright/foundation/ABitReader.h>
#include <media/stagefright/foundation/ABuffer.h>
#include <media/stagefright/foundation/ADebug.h>
@@ -41,8 +41,12 @@
#include <inttypes.h>
namespace android {
-using binder::Status;
-using MediaDescrambler::DescrambleInfo;
+using hardware::hidl_handle;
+using hardware::hidl_memory;
+using hardware::hidl_string;
+using hardware::hidl_vec;
+using namespace hardware::cas::V1_0;
+using namespace hardware::cas::native::V1_0;
// I want the expression "y" evaluated even if verbose logging is off.
#define MY_LOGV(x, y) \
@@ -203,6 +207,7 @@
sp<AMessage> mSampleAesKeyItem;
sp<IMemory> mMem;
sp<MemoryDealer> mDealer;
+ hardware::cas::native::V1_0::SharedBuffer mDescramblerSrcBuffer;
sp<ABuffer> mDescrambledBuffer;
List<SubSampleInfo> mSubSamples;
sp<IDescrambler> mDescrambler;
@@ -235,7 +240,7 @@
// Ensure internal buffers can hold specified size, and will re-allocate
// as needed.
- void ensureBufferCapacity(size_t size);
+ bool ensureBufferCapacity(size_t size);
DISALLOW_EVIL_CONSTRUCTORS(Stream);
};
@@ -807,9 +812,9 @@
mQueue = NULL;
}
-void ATSParser::Stream::ensureBufferCapacity(size_t neededSize) {
+bool ATSParser::Stream::ensureBufferCapacity(size_t neededSize) {
if (mBuffer != NULL && mBuffer->capacity() >= neededSize) {
- return;
+ return true;
}
ALOGV("ensureBufferCapacity: current size %zu, new size %zu, scrambled %d",
@@ -837,6 +842,26 @@
mMem = newMem;
mDealer = newDealer;
mDescrambledBuffer = newScrambledBuffer;
+
+ ssize_t offset;
+ size_t size;
+ sp<IMemoryHeap> heap = newMem->getMemory(&offset, &size);
+ if (heap == NULL) {
+ return false;
+ }
+ native_handle_t* nativeHandle = native_handle_create(1, 0);
+ if (!nativeHandle) {
+ ALOGE("[stream %d] failed to create native handle", mElementaryPID);
+ return false;
+ }
+ nativeHandle->data[0] = heap->getHeapID();
+ mDescramblerSrcBuffer.heapBase = hidl_memory("ashmem",
+ hidl_handle(nativeHandle), heap->getSize());
+ mDescramblerSrcBuffer.offset = (uint64_t) offset;
+ mDescramblerSrcBuffer.size = (uint64_t) size;
+
+ ALOGD("[stream %d] created shared buffer for descrambling, offset %zd, size %zu",
+ mElementaryPID, offset, size);
} else {
// Align to multiples of 64K.
neededSize = (neededSize + 65535) & ~65535;
@@ -850,6 +875,7 @@
newBuffer->setRange(0, 0);
}
mBuffer = newBuffer;
+ return true;
}
status_t ATSParser::Stream::parse(
@@ -923,7 +949,9 @@
}
size_t neededSize = mBuffer->size() + payloadSizeBits / 8;
- ensureBufferCapacity(neededSize);
+ if (!ensureBufferCapacity(neededSize)) {
+ return NO_MEMORY;
+ }
memcpy(mBuffer->data() + mBuffer->size(), br->data(), payloadSizeBits / 8);
mBuffer->setRange(0, mBuffer->size() + payloadSizeBits / 8);
@@ -1365,47 +1393,59 @@
memcpy(mDescrambledBuffer->data(), mBuffer->data(), descrambleBytes);
mDescrambledBuffer->setRange(0, descrambleBytes);
- sp<ABuffer> subSamples = new ABuffer(
- sizeof(DescramblerPlugin::SubSample) * descrambleSubSamples);
-
- DescrambleInfo info;
- info.dstType = DescrambleInfo::kDestinationTypeVmPointer;
- info.scramblingControl = (DescramblerPlugin::ScramblingControl)sctrl;
- info.numSubSamples = descrambleSubSamples;
- info.subSamples = (DescramblerPlugin::SubSample *)subSamples->data();
- info.srcMem = mMem;
- info.srcOffset = 0;
- info.dstPtr = NULL; // in-place descrambling into srcMem
- info.dstOffset = 0;
+ hidl_vec<SubSample> subSamples;
+ subSamples.resize(descrambleSubSamples);
int32_t i = 0;
for (auto it = mSubSamples.begin();
it != mSubSamples.end() && i < descrambleSubSamples; it++, i++) {
if (it->transport_scrambling_mode != 0 || pesScramblingControl != 0) {
- info.subSamples[i].mNumBytesOfClearData = 0;
- info.subSamples[i].mNumBytesOfEncryptedData = it->subSampleSize;
+ subSamples[i].numBytesOfClearData = 0;
+ subSamples[i].numBytesOfEncryptedData = it->subSampleSize;
} else {
- info.subSamples[i].mNumBytesOfClearData = it->subSampleSize;
- info.subSamples[i].mNumBytesOfEncryptedData = 0;
+ subSamples[i].numBytesOfClearData = it->subSampleSize;
+ subSamples[i].numBytesOfEncryptedData = 0;
}
}
+
+ uint64_t srcOffset = 0, dstOffset = 0;
// If scrambled at PES-level, PES header should be skipped
if (pesScramblingControl != 0) {
- info.srcOffset = info.dstOffset = pesOffset;
- info.subSamples[0].mNumBytesOfEncryptedData -= pesOffset;
+ srcOffset = dstOffset = pesOffset;
+ subSamples[0].numBytesOfEncryptedData -= pesOffset;
}
- int32_t result;
- Status status = mDescrambler->descramble(info, &result);
+ Status status = Status::OK;
+ uint32_t bytesWritten = 0;
+ hidl_string detailedError;
- if (!status.isOk()) {
- ALOGE("[stream %d] descramble failed, exceptionCode=%d",
- mElementaryPID, status.exceptionCode());
+ DestinationBuffer dstBuffer;
+ dstBuffer.type = BufferType::SHARED_MEMORY;
+ dstBuffer.nonsecureMemory = mDescramblerSrcBuffer;
+
+ auto returnVoid = mDescrambler->descramble(
+ (ScramblingControl) sctrl,
+ subSamples,
+ mDescramblerSrcBuffer,
+ srcOffset,
+ dstBuffer,
+ dstOffset,
+ [&status, &bytesWritten, &detailedError] (
+ Status _status, uint32_t _bytesWritten,
+ const hidl_string& _detailedError) {
+ status = _status;
+ bytesWritten = _bytesWritten;
+ detailedError = _detailedError;
+ });
+
+ if (!returnVoid.isOk()) {
+ ALOGE("[stream %d] descramble failed, trans=%s",
+ mElementaryPID, returnVoid.description().c_str());
return UNKNOWN_ERROR;
}
ALOGV("[stream %d] descramble succeeded, %d bytes",
- mElementaryPID, result);
+ mElementaryPID, bytesWritten);
memcpy(mBuffer->data(), mDescrambledBuffer->data(), descrambleBytes);
}
diff --git a/media/libstagefright/mpeg2ts/ATSParser.h b/media/libstagefright/mpeg2ts/ATSParser.h
index 374e011..41c19cd 100644
--- a/media/libstagefright/mpeg2ts/ATSParser.h
+++ b/media/libstagefright/mpeg2ts/ATSParser.h
@@ -29,11 +29,13 @@
#include <vector>
namespace android {
-namespace media {
-class ICas;
-class IDescrambler;
-};
-using namespace media;
+namespace hardware {
+namespace cas {
+namespace V1_0 {
+struct ICas;
+}}}
+using hardware::cas::V1_0::ICas;
+
class ABitReader;
struct ABuffer;
struct AnotherPacketSource;
diff --git a/media/libstagefright/mpeg2ts/Android.bp b/media/libstagefright/mpeg2ts/Android.bp
index 96eb5bf..21259c4 100644
--- a/media/libstagefright/mpeg2ts/Android.bp
+++ b/media/libstagefright/mpeg2ts/Android.bp
@@ -35,5 +35,8 @@
shared_libs: [
"libcrypto",
"libmedia",
+ "libhidlmemory",
+ "android.hardware.cas.native@1.0",
+ "android.hidl.memory@1.0",
],
}
diff --git a/media/libstagefright/mpeg2ts/CasManager.cpp b/media/libstagefright/mpeg2ts/CasManager.cpp
index 047b1b3..9ff4521 100644
--- a/media/libstagefright/mpeg2ts/CasManager.cpp
+++ b/media/libstagefright/mpeg2ts/CasManager.cpp
@@ -18,15 +18,19 @@
#define LOG_TAG "CasManager"
#include "CasManager.h"
-#include <android/media/ICas.h>
-#include <android/media/IDescrambler.h>
-#include <android/media/IMediaCasService.h>
-#include <binder/IServiceManager.h>
+#include <android/hardware/cas/1.0/ICas.h>
+#include <android/hardware/cas/1.0/IMediaCasService.h>
+#include <android/hardware/cas/native/1.0/IDescrambler.h>
+#include <hidl/HidlSupport.h>
#include <media/stagefright/foundation/ABitReader.h>
#include <utils/Log.h>
namespace android {
-using binder::Status;
+
+using hardware::hidl_vec;
+using hardware::Return;
+using namespace hardware::cas::V1_0;
+using namespace hardware::cas::native::V1_0;
struct ATSParser::CasManager::ProgramCasManager : public RefBase {
ProgramCasManager(unsigned programNumber, const CADescriptor &descriptor);
@@ -125,45 +129,60 @@
const sp<ICas>& cas,
PidToSessionMap &sessionMap,
CasSession *session) {
- sp<IServiceManager> sm = defaultServiceManager();
- sp<IBinder> casServiceBinder = sm->getService(String16("media.cas"));
- sp<IMediaCasService> casService =
- interface_cast<IMediaCasService>(casServiceBinder);
-
+ sp<IMediaCasService> casService = IMediaCasService::getService("default");
if (casService == NULL) {
ALOGE("Cannot obtain IMediaCasService");
return NO_INIT;
}
+ Status status;
sp<IDescrambler> descrambler;
+ sp<IDescramblerBase> descramblerBase;
+ Return<Status> returnStatus(Status::OK);
+ Return<sp<IDescramblerBase> > returnDescrambler(NULL);
std::vector<uint8_t> sessionId;
const CADescriptor &descriptor = session->mCADescriptor;
- Status status = cas->openSession(&sessionId);
- if (!status.isOk()) {
- ALOGE("Failed to open session: exception=%d, error=%d",
- status.exceptionCode(), status.serviceSpecificErrorCode());
+ auto returnVoid = cas->openSession(
+ [&status, &sessionId] (Status _status, const hidl_vec<uint8_t>& _sessionId) {
+ status = _status;
+ sessionId = _sessionId;
+ });
+ if (!returnVoid.isOk() || status != Status::OK) {
+ ALOGE("Failed to open session: trans=%s, status=%d",
+ returnVoid.description().c_str(), status);
goto l_fail;
}
- cas->setSessionPrivateData(sessionId, descriptor.mPrivateData);
- if (!status.isOk()) {
- ALOGE("Failed to set private data: exception=%d, error=%d",
- status.exceptionCode(), status.serviceSpecificErrorCode());
+ returnStatus = cas->setSessionPrivateData(sessionId, descriptor.mPrivateData);
+ if (!returnStatus.isOk() || returnStatus != Status::OK) {
+ ALOGE("Failed to set private data: trans=%s, status=%d",
+ returnStatus.description().c_str(), (Status)returnStatus);
goto l_fail;
}
- status = casService->createDescrambler(descriptor.mSystemID, &descrambler);
- if (!status.isOk() || descrambler == NULL) {
- ALOGE("Failed to create descrambler: : exception=%d, error=%d",
- status.exceptionCode(), status.serviceSpecificErrorCode());
+ returnDescrambler = casService->createDescrambler(descriptor.mSystemID);
+ if (!returnDescrambler.isOk()) {
+ ALOGE("Failed to create descrambler: trans=%s",
+ returnDescrambler.description().c_str());
+ goto l_fail;
+ }
+ descramblerBase = (sp<IDescramblerBase>) returnDescrambler;
+ if (descramblerBase == NULL) {
+ ALOGE("Failed to create descrambler: null ptr");
goto l_fail;
}
- status = descrambler->setMediaCasSession(sessionId);
- if (!status.isOk()) {
- ALOGE("Failed to init descrambler: : exception=%d, error=%d",
- status.exceptionCode(), status.serviceSpecificErrorCode());
+ returnStatus = descramblerBase->setMediaCasSession(sessionId);
+ if (!returnStatus.isOk() || (Status) returnStatus != Status::OK) {
+ ALOGE("Failed to init descrambler: : trans=%s, status=%d",
+ returnStatus.description().c_str(), (Status) returnStatus);
+ goto l_fail;
+ }
+
+ descrambler = IDescrambler::castFrom(descramblerBase);
+ if (descrambler == NULL) {
+ ALOGE("Failed to cast from IDescramblerBase to IDescrambler");
goto l_fail;
}
@@ -177,8 +196,8 @@
if (!sessionId.empty()) {
cas->closeSession(sessionId);
}
- if (descrambler != NULL) {
- descrambler->release();
+ if (descramblerBase != NULL) {
+ descramblerBase->release();
}
return NO_INIT;
}
@@ -316,11 +335,12 @@
if (index < 0) {
return false;
}
- MediaCas::ParcelableCasData ecm(br->data(), br->numBitsLeft() / 8);
- Status status = mICas->processEcm(mCAPidToSessionIdMap[index], ecm);
- if (!status.isOk()) {
- ALOGE("Failed to process ECM: exception=%d, error=%d",
- status.exceptionCode(), status.serviceSpecificErrorCode());
+ hidl_vec<uint8_t> ecm;
+ ecm.setToExternal((uint8_t*)br->data(), br->numBitsLeft() / 8);
+ auto returnStatus = mICas->processEcm(mCAPidToSessionIdMap[index], ecm);
+ if (!returnStatus.isOk() || (Status) returnStatus != Status::OK) {
+ ALOGE("Failed to process ECM: trans=%s, status=%d",
+ returnStatus.description().c_str(), (Status) returnStatus);
}
return true; // handled
}
diff --git a/media/libstagefright/mpeg2ts/CasManager.h b/media/libstagefright/mpeg2ts/CasManager.h
index 8088dec..81f6546 100644
--- a/media/libstagefright/mpeg2ts/CasManager.h
+++ b/media/libstagefright/mpeg2ts/CasManager.h
@@ -21,10 +21,13 @@
#include <set>
namespace android {
-namespace media {
-class ICas;
-class IDescrambler;
-}
+namespace hardware {
+namespace cas {
+namespace native {
+namespace V1_0 {
+struct IDescrambler;
+}}}}
+using hardware::cas::native::V1_0::IDescrambler;
struct ATSParser::CasManager : public RefBase {
CasManager();
diff --git a/media/libstagefright/mpeg2ts/MPEG2TSExtractor.cpp b/media/libstagefright/mpeg2ts/MPEG2TSExtractor.cpp
index c3f1274..9d684e0 100644
--- a/media/libstagefright/mpeg2ts/MPEG2TSExtractor.cpp
+++ b/media/libstagefright/mpeg2ts/MPEG2TSExtractor.cpp
@@ -38,8 +38,13 @@
#include "AnotherPacketSource.h"
#include "ATSParser.h"
+#include <hidl/HybridInterface.h>
+#include <android/hardware/cas/1.0/ICas.h>
+
namespace android {
+using hardware::cas::V1_0::ICas;
+
static const size_t kTSPacketSize = 188;
static const int kMaxDurationReadSize = 250000LL;
static const int kMaxDurationRetry = 6;
@@ -156,7 +161,10 @@
|| !strcasecmp(MEDIA_MIMETYPE_AUDIO_SCRAMBLED, mime));
}
-status_t MPEG2TSExtractor::setMediaCas(const sp<ICas> &cas) {
+status_t MPEG2TSExtractor::setMediaCas(const HInterfaceToken &casToken) {
+ HalToken halToken;
+ halToken.setToExternal((uint8_t*)casToken.data(), casToken.size());
+ sp<ICas> cas = ICas::castFrom(retrieveHalInterface(halToken));
ALOGD("setMediaCas: %p", cas.get());
status_t err = mParser->setMediaCas(cas);
diff --git a/services/mediadrm/Android.mk b/services/mediadrm/Android.mk
index 6b30db6..2daa829 100644
--- a/services/mediadrm/Android.mk
+++ b/services/mediadrm/Android.mk
@@ -17,7 +17,6 @@
include $(CLEAR_VARS)
LOCAL_SRC_FILES:= \
- MediaCasService.cpp \
MediaDrmService.cpp \
main_mediadrmserver.cpp
diff --git a/services/mediadrm/FactoryLoader.h b/services/mediadrm/FactoryLoader.h
deleted file mode 100644
index d7f1118..0000000
--- a/services/mediadrm/FactoryLoader.h
+++ /dev/null
@@ -1,220 +0,0 @@
-/*
- * 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 MEDIA_CAS_LOADER_H_
-#define MEDIA_CAS_LOADER_H_
-
-#include <dirent.h>
-#include <dlfcn.h>
-#include <media/SharedLibrary.h>
-#include <utils/KeyedVector.h>
-#include <utils/Mutex.h>
-
-namespace android {
-using namespace std;
-using namespace media;
-using namespace MediaCas;
-
-template <class T>
-class FactoryLoader {
-public:
- FactoryLoader(const char *name) :
- mFactory(NULL), mCreateFactoryFuncName(name) {}
-
- virtual ~FactoryLoader() { closeFactory(); }
-
- bool findFactoryForScheme(
- int32_t CA_system_id,
- sp<SharedLibrary> *library = NULL,
- T** factory = NULL);
-
- bool enumeratePlugins(vector<ParcelableCasPluginDescriptor>* results);
-
-private:
- typedef T*(*CreateFactoryFunc)();
-
- Mutex mMapLock;
- T* mFactory;
- const char *mCreateFactoryFuncName;
- sp<SharedLibrary> mLibrary;
- KeyedVector<int32_t, String8> mCASystemIdToLibraryPathMap;
- KeyedVector<String8, wp<SharedLibrary> > mLibraryPathToOpenLibraryMap;
-
- bool loadFactoryForSchemeFromPath(
- const String8 &path,
- int32_t CA_system_id,
- sp<SharedLibrary> *library,
- T** factory);
-
- bool queryPluginsFromPath(
- const String8 &path,
- vector<ParcelableCasPluginDescriptor>* results);
-
- bool openFactory(const String8 &path);
- void closeFactory();
-};
-
-template <class T>
-bool FactoryLoader<T>::findFactoryForScheme(
- int32_t CA_system_id, sp<SharedLibrary> *library, T** factory) {
- if (library != NULL) {
- library->clear();
- }
- if (factory != NULL) {
- *factory = NULL;
- }
-
- Mutex::Autolock autoLock(mMapLock);
-
- // first check cache
- ssize_t index = mCASystemIdToLibraryPathMap.indexOfKey(CA_system_id);
- if (index >= 0) {
- return loadFactoryForSchemeFromPath(
- mCASystemIdToLibraryPathMap[index],
- CA_system_id, library, factory);
- }
-
- // no luck, have to search
- String8 dirPath("/system/lib/mediacas");
- DIR* pDir = opendir(dirPath.string());
-
- if (pDir == NULL) {
- ALOGE("Failed to open plugin directory %s", dirPath.string());
- return false;
- }
-
- struct dirent* pEntry;
- while ((pEntry = readdir(pDir))) {
- String8 pluginPath = dirPath + "/" + pEntry->d_name;
- if (pluginPath.getPathExtension() == ".so") {
- if (loadFactoryForSchemeFromPath(
- pluginPath, CA_system_id, library, factory)) {
- mCASystemIdToLibraryPathMap.add(CA_system_id, pluginPath);
- closedir(pDir);
-
- return true;
- }
- }
- }
-
- closedir(pDir);
-
- ALOGE("Failed to find plugin");
- return false;
-}
-
-template <class T>
-bool FactoryLoader<T>::enumeratePlugins(
- vector<ParcelableCasPluginDescriptor>* results) {
- ALOGI("enumeratePlugins");
-
- results->clear();
-
- String8 dirPath("/system/lib/mediacas");
- DIR* pDir = opendir(dirPath.string());
-
- if (pDir == NULL) {
- ALOGE("Failed to open plugin directory %s", dirPath.string());
- return false;
- }
-
- Mutex::Autolock autoLock(mMapLock);
-
- struct dirent* pEntry;
- while ((pEntry = readdir(pDir))) {
- String8 pluginPath = dirPath + "/" + pEntry->d_name;
- if (pluginPath.getPathExtension() == ".so") {
- queryPluginsFromPath(pluginPath, results);
- }
- }
- return true;
-}
-
-template <class T>
-bool FactoryLoader<T>::loadFactoryForSchemeFromPath(
- const String8 &path, int32_t CA_system_id,
- sp<SharedLibrary> *library, T** factory) {
- closeFactory();
-
- if (!openFactory(path) || !mFactory->isSystemIdSupported(CA_system_id)) {
- closeFactory();
- return false;
- }
-
- if (library != NULL) {
- *library = mLibrary;
- }
- if (factory != NULL) {
- *factory = mFactory;
- }
- return true;
-}
-
-template <class T>
-bool FactoryLoader<T>::queryPluginsFromPath(
- const String8 &path, vector<ParcelableCasPluginDescriptor>* results) {
- closeFactory();
-
- vector<CasPluginDescriptor> descriptors;
- if (!openFactory(path) || mFactory->queryPlugins(&descriptors) != OK) {
- closeFactory();
- return false;
- }
-
- for (auto it = descriptors.begin(); it != descriptors.end(); it++) {
- results->push_back(ParcelableCasPluginDescriptor(
- it->CA_system_id, it->name));
- }
- return true;
-}
-
-template <class T>
-bool FactoryLoader<T>::openFactory(const String8 &path) {
- // get strong pointer to open shared library
- ssize_t index = mLibraryPathToOpenLibraryMap.indexOfKey(path);
- if (index >= 0) {
- mLibrary = mLibraryPathToOpenLibraryMap[index].promote();
- } else {
- index = mLibraryPathToOpenLibraryMap.add(path, NULL);
- }
-
- if (!mLibrary.get()) {
- mLibrary = new SharedLibrary(path);
- if (!*mLibrary) {
- return false;
- }
-
- mLibraryPathToOpenLibraryMap.replaceValueAt(index, mLibrary);
- }
-
- CreateFactoryFunc createFactory =
- (CreateFactoryFunc)mLibrary->lookup(mCreateFactoryFuncName);
- if (createFactory == NULL || (mFactory = createFactory()) == NULL) {
- return false;
- }
- return true;
-}
-
-template <class T>
-void FactoryLoader<T>::closeFactory() {
- delete mFactory;
- mFactory = NULL;
- mLibrary.clear();
-}
-
-} // namespace android
-
-#endif // MEDIA_CAS_LOADER_H_
diff --git a/services/mediadrm/MediaCasService.cpp b/services/mediadrm/MediaCasService.cpp
deleted file mode 100644
index c111283..0000000
--- a/services/mediadrm/MediaCasService.cpp
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * 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.
- */
-
-//#define LOG_NDEBUG 0
-#define LOG_TAG "MediaCasService"
-
-#include <binder/IServiceManager.h>
-#include <media/cas/CasAPI.h>
-#include <media/cas/DescramblerAPI.h>
-#include <media/CasImpl.h>
-#include <media/DescramblerImpl.h>
-#include <utils/Log.h>
-#include <utils/List.h>
-#include "MediaCasService.h"
-#include <android/media/ICasListener.h>
-
-namespace android {
-
-//static
-void MediaCasService::instantiate() {
- defaultServiceManager()->addService(
- String16("media.cas"), new MediaCasService());
-}
-
-MediaCasService::MediaCasService() :
- mCasLoader(new FactoryLoader<CasFactory>("createCasFactory")),
- mDescramblerLoader(new FactoryLoader<DescramblerFactory>(
- "createDescramblerFactory")) {
-}
-
-MediaCasService::~MediaCasService() {
- delete mCasLoader;
- delete mDescramblerLoader;
-}
-
-Status MediaCasService::enumeratePlugins(
- vector<ParcelableCasPluginDescriptor>* results) {
- ALOGV("enumeratePlugins");
-
- mCasLoader->enumeratePlugins(results);
-
- return Status::ok();
-}
-
-Status MediaCasService::isSystemIdSupported(
- int32_t CA_system_id, bool* result) {
- ALOGV("isSystemIdSupported: CA_system_id=%d", CA_system_id);
-
- *result = mCasLoader->findFactoryForScheme(CA_system_id);
-
- return Status::ok();
-}
-
-Status MediaCasService::createPlugin(
- int32_t CA_system_id,
- const sp<ICasListener> &listener,
- sp<ICas>* result) {
- ALOGV("createPlugin: CA_system_id=%d", CA_system_id);
-
- result->clear();
-
- CasFactory *factory;
- sp<SharedLibrary> library;
- if (mCasLoader->findFactoryForScheme(CA_system_id, &library, &factory)) {
- CasPlugin *plugin = NULL;
- sp<CasImpl> casImpl = new CasImpl(listener);
- if (factory->createPlugin(CA_system_id, (uint64_t)casImpl.get(),
- &CasImpl::OnEvent, &plugin) == OK && plugin != NULL) {
- casImpl->init(library, plugin);
- *result = casImpl;
- }
- }
-
- return Status::ok();
-}
-
-Status MediaCasService::isDescramblerSupported(
- int32_t CA_system_id, bool* result) {
- ALOGV("isDescramblerSupported: CA_system_id=%d", CA_system_id);
-
- *result = mDescramblerLoader->findFactoryForScheme(CA_system_id);
-
- return Status::ok();
-}
-
-Status MediaCasService::createDescrambler(
- int32_t CA_system_id, sp<IDescrambler>* result) {
- ALOGV("createDescrambler: CA_system_id=%d", CA_system_id);
-
- result->clear();
-
- DescramblerFactory *factory;
- sp<SharedLibrary> library;
- if (mDescramblerLoader->findFactoryForScheme(
- CA_system_id, &library, &factory)) {
- DescramblerPlugin *plugin = NULL;
- if (factory->createPlugin(CA_system_id, &plugin) == OK
- && plugin != NULL) {
- *result = new DescramblerImpl(library, plugin);
- }
- }
-
- return Status::ok();
-}
-
-} // namespace android
diff --git a/services/mediadrm/MediaCasService.h b/services/mediadrm/MediaCasService.h
deleted file mode 100644
index cb828f2..0000000
--- a/services/mediadrm/MediaCasService.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * 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 MEDIA_CAS_SERVICE_H_
-#define MEDIA_CAS_SERVICE_H_
-
-#include <android/media/BnMediaCasService.h>
-
-#include "FactoryLoader.h"
-
-namespace android {
-using binder::Status;
-struct CasFactory;
-struct DescramblerFactory;
-
-class MediaCasService : public BnMediaCasService {
-public:
- static void instantiate();
-
- virtual Status enumeratePlugins(
- vector<ParcelableCasPluginDescriptor>* results) override;
-
- virtual Status isSystemIdSupported(
- int32_t CA_system_id, bool* result) override;
-
- virtual Status createPlugin(
- int32_t CA_system_id,
- const sp<ICasListener> &listener,
- sp<ICas>* result) override;
-
- virtual Status isDescramblerSupported(
- int32_t CA_system_id, bool* result) override;
-
- virtual Status createDescrambler(
- int32_t CA_system_id, sp<IDescrambler>* result) override;
-
-private:
- FactoryLoader<CasFactory> *mCasLoader;
- FactoryLoader<DescramblerFactory> *mDescramblerLoader;
-
- MediaCasService();
- virtual ~MediaCasService();
-};
-
-} // namespace android
-
-#endif // MEDIA_CAS_SERVICE_H_
diff --git a/services/mediadrm/main_mediadrmserver.cpp b/services/mediadrm/main_mediadrmserver.cpp
index b685ae0..b767b8c 100644
--- a/services/mediadrm/main_mediadrmserver.cpp
+++ b/services/mediadrm/main_mediadrmserver.cpp
@@ -27,7 +27,6 @@
#include <cutils/properties.h>
#include <utils/Log.h>
#include "MediaDrmService.h"
-#include "MediaCasService.h"
using namespace android;
@@ -39,7 +38,6 @@
sp<IServiceManager> sm = defaultServiceManager();
ALOGI("ServiceManager: %p", sm.get());
MediaDrmService::instantiate();
- MediaCasService::instantiate();
ProcessState::self()->startThreadPool();
IPCThreadState::self()->joinThreadPool();
}