Add mediadrm service
Part of media security hardening
This is an intermediate step toward moving
mediadrm to a new service separate from mediaserver.
This first step allows mediadrmservice to run based
on the system property media.mediadrmservice.enable
so it can be selectively enabled on devices that
support using native_handles for secure buffers.
bug: 22990512
Change-Id: I70320f0c4b7861cdba26fbc24c20bce54e5749a4
diff --git a/media/libmedia/Android.mk b/media/libmedia/Android.mk
index c095724..479ccbb 100644
--- a/media/libmedia/Android.mk
+++ b/media/libmedia/Android.mk
@@ -31,6 +31,7 @@
mediaplayer.cpp \
IMediaCodecList.cpp \
IMediaCodecService.cpp \
+ IMediaDrmService.cpp \
IMediaHTTPConnection.cpp \
IMediaHTTPService.cpp \
IMediaLogService.cpp \
diff --git a/media/libmedia/IMediaDrmService.cpp b/media/libmedia/IMediaDrmService.cpp
new file mode 100644
index 0000000..9b6ecfd
--- /dev/null
+++ b/media/libmedia/IMediaDrmService.cpp
@@ -0,0 +1,88 @@
+/*
+**
+** Copyright 2015, 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 <stdint.h>
+#include <sys/types.h>
+
+#include <binder/Parcel.h>
+#include <binder/IMemory.h>
+#include <media/ICrypto.h>
+#include <media/IDrm.h>
+#include <media/IMediaDrmService.h>
+
+#include <utils/Errors.h> // for status_t
+#include <utils/String8.h>
+
+namespace android {
+
+enum {
+ MAKE_CRYPTO = IBinder::FIRST_CALL_TRANSACTION,
+ MAKE_DRM,
+};
+
+class BpMediaDrmService: public BpInterface<IMediaDrmService>
+{
+public:
+ BpMediaDrmService(const sp<IBinder>& impl)
+ : BpInterface<IMediaDrmService>(impl)
+ {
+ }
+
+ virtual sp<ICrypto> makeCrypto() {
+ Parcel data, reply;
+ data.writeInterfaceToken(IMediaDrmService::getInterfaceDescriptor());
+ remote()->transact(MAKE_CRYPTO, data, &reply);
+ return interface_cast<ICrypto>(reply.readStrongBinder());
+ }
+
+ virtual sp<IDrm> makeDrm() {
+ Parcel data, reply;
+ data.writeInterfaceToken(IMediaDrmService::getInterfaceDescriptor());
+ remote()->transact(MAKE_DRM, data, &reply);
+ return interface_cast<IDrm>(reply.readStrongBinder());
+ }
+
+};
+
+IMPLEMENT_META_INTERFACE(MediaDrmService, "android.media.IMediaDrmService");
+
+// ----------------------------------------------------------------------
+
+status_t BnMediaDrmService::onTransact(
+ uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
+{
+ switch (code) {
+ case MAKE_CRYPTO: {
+ CHECK_INTERFACE(IMediaDrmService, data, reply);
+ sp<ICrypto> crypto = makeCrypto();
+ reply->writeStrongBinder(IInterface::asBinder(crypto));
+ return NO_ERROR;
+ } break;
+ case MAKE_DRM: {
+ CHECK_INTERFACE(IMediaDrmService, data, reply);
+ sp<IDrm> drm = makeDrm();
+ reply->writeStrongBinder(IInterface::asBinder(drm));
+ return NO_ERROR;
+ } break;
+ default:
+ return BBinder::onTransact(code, data, reply, flags);
+ }
+}
+
+// ----------------------------------------------------------------------------
+
+} // namespace android
diff --git a/media/ndk/Android.mk b/media/ndk/Android.mk
index 6546f14..8dbb291 100644
--- a/media/ndk/Android.mk
+++ b/media/ndk/Android.mk
@@ -47,6 +47,7 @@
libstagefright_foundation \
liblog \
libutils \
+ libcutils \
libandroid_runtime \
libbinder \
libgui \
diff --git a/media/ndk/NdkMediaCrypto.cpp b/media/ndk/NdkMediaCrypto.cpp
index 1cc2f1a..af8ffea 100644
--- a/media/ndk/NdkMediaCrypto.cpp
+++ b/media/ndk/NdkMediaCrypto.cpp
@@ -23,10 +23,12 @@
#include "NdkMediaFormatPriv.h"
+#include <cutils/properties.h>
#include <utils/Log.h>
#include <utils/StrongPointer.h>
#include <binder/IServiceManager.h>
#include <media/ICrypto.h>
+#include <media/IMediaDrmService.h>
#include <media/IMediaPlayerService.h>
#include <android_runtime/AndroidRuntime.h>
#include <android_util_Binder.h>
@@ -46,19 +48,30 @@
static sp<ICrypto> makeCrypto() {
sp<IServiceManager> sm = defaultServiceManager();
+ sp<ICrypto> crypto;
- sp<IBinder> binder =
- sm->getService(String16("media.player"));
-
- sp<IMediaPlayerService> service =
- interface_cast<IMediaPlayerService>(binder);
-
- if (service == NULL) {
- return NULL;
+ char value[PROPERTY_VALUE_MAX];
+ if (property_get("media.mediadrmservice.enable", value, NULL)
+ && (!strcmp("1", value) || !strcasecmp("true", value))) {
+ sp<IBinder> binder =
+ sm->getService(String16("media.drm"));
+ sp<IMediaDrmService> service =
+ interface_cast<IMediaDrmService>(binder);
+ if (service == NULL) {
+ return NULL;
+ }
+ crypto = service->makeCrypto();
+ } else {
+ sp<IBinder> binder =
+ sm->getService(String16("media.player"));
+ sp<IMediaPlayerService> service =
+ interface_cast<IMediaPlayerService>(binder);
+ if (service == NULL) {
+ return NULL;
+ }
+ crypto = service->makeCrypto();
}
- sp<ICrypto> crypto = service->makeCrypto();
-
if (crypto == NULL || (crypto->initCheck() != OK && crypto->initCheck() != NO_INIT)) {
return NULL;
}
diff --git a/media/ndk/NdkMediaDrm.cpp b/media/ndk/NdkMediaDrm.cpp
index 83a5ba1..ea47d57 100644
--- a/media/ndk/NdkMediaDrm.cpp
+++ b/media/ndk/NdkMediaDrm.cpp
@@ -19,6 +19,7 @@
#include "NdkMediaDrm.h"
+#include <cutils/properties.h>
#include <utils/Log.h>
#include <utils/StrongPointer.h>
#include <gui/Surface.h>
@@ -27,6 +28,7 @@
#include <media/IDrmClient.h>
#include <media/stagefright/MediaErrors.h>
#include <binder/IServiceManager.h>
+#include <media/IMediaDrmService.h>
#include <media/IMediaPlayerService.h>
#include <ndk/NdkMediaCrypto.h>
@@ -148,19 +150,30 @@
static sp<IDrm> CreateDrm() {
sp<IServiceManager> sm = defaultServiceManager();
+ sp<IDrm> drm;
- sp<IBinder> binder =
- sm->getService(String16("media.player"));
-
- sp<IMediaPlayerService> service =
- interface_cast<IMediaPlayerService>(binder);
-
- if (service == NULL) {
- return NULL;
+ char value[PROPERTY_VALUE_MAX];
+ if (property_get("media.mediadrmservice.enable", value, NULL)
+ && (!strcmp("1", value) || !strcasecmp("true", value))) {
+ sp<IBinder> binder =
+ sm->getService(String16("media.drm"));
+ sp<IMediaDrmService> service =
+ interface_cast<IMediaDrmService>(binder);
+ if (service == NULL) {
+ return NULL;
+ }
+ drm = service->makeDrm();
+ } else {
+ sp<IBinder> binder =
+ sm->getService(String16("media.player"));
+ sp<IMediaPlayerService> service =
+ interface_cast<IMediaPlayerService>(binder);
+ if (service == NULL) {
+ return NULL;
+ }
+ drm = service->makeDrm();
}
- sp<IDrm> drm = service->makeDrm();
-
if (drm == NULL || (drm->initCheck() != OK && drm->initCheck() != NO_INIT)) {
return NULL;
}