DrmUtils: refactor IDrm/ICrypto creation
Added utilities to:
* Query config for IMediaDrmService usage
* Create remote vs local IDrm/ICrypto object based on aforementioned config
Bug: 134787536
Test: MediaDrmClearkeyTest#testClearKeyPlaybackCenc
Change-Id: I72df528c0bbd8a6dbd3c4962ac91eb89696bcaf7
diff --git a/drm/libmediadrm/Android.bp b/drm/libmediadrm/Android.bp
index 52c7438..b3fd7e9 100644
--- a/drm/libmediadrm/Android.bp
+++ b/drm/libmediadrm/Android.bp
@@ -24,6 +24,7 @@
"SharedLibrary.cpp",
"DrmHal.cpp",
"CryptoHal.cpp",
+ "DrmUtils.cpp",
],
local_include_dirs: [
@@ -58,6 +59,12 @@
"libhidlbase",
],
+ export_shared_lib_headers: [
+ "android.hardware.drm@1.0",
+ "android.hardware.drm@1.1",
+ "android.hardware.drm@1.2",
+ ],
+
cflags: [
"-Werror",
"-Wall",
diff --git a/drm/libmediadrm/DrmSessionManager.cpp b/drm/libmediadrm/DrmSessionManager.cpp
index 0b91b85..165a4d6 100644
--- a/drm/libmediadrm/DrmSessionManager.cpp
+++ b/drm/libmediadrm/DrmSessionManager.cpp
@@ -25,6 +25,7 @@
#include <binder/IServiceManager.h>
#include <cutils/properties.h>
#include <media/MediaResource.h>
+#include <mediadrm/DrmUtils.h>
#include <mediadrm/DrmSessionManager.h>
#include <unistd.h>
#include <utils/String8.h>
@@ -62,7 +63,8 @@
}
static sp<IResourceManagerService> getResourceManagerService() {
- if (property_get_bool("persist.device_config.media_native.mediadrmserver", 1)) {
+ if (DrmUtils::UseDrmService()) {
+ // Create ResourceManagerService object in mediadrmserver process
return new android::media::ResourceManagerService();
}
sp<IServiceManager> sm = defaultServiceManager();
diff --git a/drm/libmediadrm/DrmUtils.cpp b/drm/libmediadrm/DrmUtils.cpp
new file mode 100644
index 0000000..7cc1697
--- /dev/null
+++ b/drm/libmediadrm/DrmUtils.cpp
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2019 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 "DrmUtils"
+
+#include <utils/String16.h>
+#include <binder/IInterface.h>
+#include <binder/IServiceManager.h>
+#include <cutils/properties.h>
+
+#include <mediadrm/CryptoHal.h>
+#include <mediadrm/DrmHal.h>
+#include <mediadrm/DrmUtils.h>
+#include <mediadrm/ICrypto.h>
+#include <mediadrm/IDrm.h>
+#include <mediadrm/IMediaDrmService.h>
+
+namespace android {
+namespace DrmUtils {
+
+namespace {
+template<typename Iface>
+sp<Iface> MakeObjectWithService(status_t *pstatus) {
+ status_t err = OK;
+ status_t &status = pstatus ? *pstatus : err;
+ sp<IServiceManager> sm = defaultServiceManager();
+ sp<IBinder> binder = sm->getService(String16("media.drm"));
+
+ sp<IMediaDrmService> service = interface_cast<IMediaDrmService>(binder);
+ if (service == NULL) {
+ status = UNKNOWN_ERROR;
+ return NULL;
+ }
+
+ auto obj = service->makeObject<Iface>();
+ if (obj == NULL) {
+ status = UNKNOWN_ERROR;
+ return NULL;
+ }
+
+ status = obj->initCheck();
+ if (status != OK && status != NO_INIT) {
+ return NULL;
+ }
+ return obj;
+}
+
+template<typename Iface, typename Hal>
+sp<Iface> MakeObject(status_t *pstatus) {
+ if (UseDrmService()) {
+ return MakeObjectWithService<Iface>(pstatus);
+ } else {
+ return new Hal();
+ }
+}
+} // namespace
+
+bool UseDrmService() {
+ return property_get_bool("persist.device_config.media_native.mediadrmserver", true);
+}
+
+sp<IDrm> MakeDrm(status_t *pstatus) {
+ return MakeObject<IDrm, DrmHal>(pstatus);
+}
+
+sp<ICrypto> MakeCrypto(status_t *pstatus) {
+ return MakeObject<ICrypto, CryptoHal>(pstatus);
+}
+
+} // namespace DrmUtils
+} // namespace android
diff --git a/drm/libmediadrm/IMediaDrmService.cpp b/drm/libmediadrm/IMediaDrmService.cpp
index f320d0b..0b650f2 100644
--- a/drm/libmediadrm/IMediaDrmService.cpp
+++ b/drm/libmediadrm/IMediaDrmService.cpp
@@ -85,4 +85,14 @@
// ----------------------------------------------------------------------------
+template<>
+sp<IDrm> IMediaDrmService::makeObject<IDrm>() {
+ return makeDrm();
+}
+
+template<>
+sp<ICrypto> IMediaDrmService::makeObject<ICrypto>() {
+ return makeCrypto();
+}
+
} // namespace android
diff --git a/drm/libmediadrm/include/mediadrm/IMediaDrmService.h b/drm/libmediadrm/include/mediadrm/IMediaDrmService.h
index 323fae5..7dcce94 100644
--- a/drm/libmediadrm/include/mediadrm/IMediaDrmService.h
+++ b/drm/libmediadrm/include/mediadrm/IMediaDrmService.h
@@ -33,8 +33,12 @@
public:
DECLARE_META_INTERFACE(MediaDrmService);
+
virtual sp<ICrypto> makeCrypto() = 0;
virtual sp<IDrm> makeDrm() = 0;
+
+ template<typename I> sp<I> makeObject();
+
};
// ----------------------------------------------------------------------------
diff --git a/drm/libmediadrm/interface/mediadrm/DrmUtils.h b/drm/libmediadrm/interface/mediadrm/DrmUtils.h
new file mode 100644
index 0000000..2cd3e6d
--- /dev/null
+++ b/drm/libmediadrm/interface/mediadrm/DrmUtils.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_DRMUTILS_H
+#define ANDROID_DRMUTILS_H
+
+#include <utils/Errors.h> // for status_t
+#include <utils/StrongPointer.h>
+
+namespace android {
+
+struct ICrypto;
+struct IDrm;
+
+namespace DrmUtils {
+
+bool UseDrmService();
+
+sp<IDrm> MakeDrm(status_t *pstatus = nullptr);
+
+sp<ICrypto> MakeCrypto(status_t *pstatus = nullptr);
+
+} // namespace DrmUtils
+
+} // namespace android
+
+#endif // ANDROID_DRMUTILS_H
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDrm.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDrm.cpp
index 2d0c9e0..6788b56 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDrm.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDrm.cpp
@@ -19,8 +19,7 @@
#include "NuPlayerDrm.h"
-#include <binder/IServiceManager.h>
-#include <mediadrm/IMediaDrmService.h>
+#include <mediadrm/DrmUtils.h>
#include <utils/Log.h>
@@ -30,60 +29,13 @@
sp<IDrm> NuPlayerDrm::CreateDrm(status_t *pstatus)
{
- status_t &status = *pstatus;
- sp<IServiceManager> sm = defaultServiceManager();
- sp<IBinder> binder = sm->getService(String16("media.drm"));
- ALOGV("CreateDrm binder %p", (binder != NULL ? binder.get() : 0));
-
- sp<IMediaDrmService> service = interface_cast<IMediaDrmService>(binder);
- if (service == NULL) {
- ALOGE("CreateDrm failed at IMediaDrmService");
- return NULL;
- }
-
- sp<IDrm> drm = service->makeDrm();
- if (drm == NULL) {
- ALOGE("CreateDrm failed at makeDrm");
- return NULL;
- }
-
- // this is before plugin creation so NO_INIT is fine
- status = drm->initCheck();
- if (status != OK && status != NO_INIT) {
- ALOGE("CreateDrm failed drm->initCheck(): %d", status);
- return NULL;
- }
- return drm;
+ return DrmUtils::MakeDrm(pstatus);
}
sp<ICrypto> NuPlayerDrm::createCrypto(status_t *pstatus)
{
- status_t &status = *pstatus;
- sp<IServiceManager> sm = defaultServiceManager();
- sp<IBinder> binder = sm->getService(String16("media.drm"));
- sp<IMediaDrmService> service = interface_cast<IMediaDrmService>(binder);
- if (service == NULL) {
- status = UNKNOWN_ERROR;
- ALOGE("CreateCrypto failed at IMediaDrmService");
- return NULL;
- }
-
- sp<ICrypto> crypto = service->makeCrypto();
- if (crypto == NULL) {
- status = UNKNOWN_ERROR;
- ALOGE("createCrypto failed");
- return NULL;
- }
-
- // this is before plugin creation so NO_INIT is fine
- status = crypto->initCheck();
- if (status != OK && status != NO_INIT) {
- ALOGE("createCrypto failed crypto->initCheck(): %d", status);
- return NULL;
- }
-
- return crypto;
+ return DrmUtils::MakeCrypto(pstatus);
}
Vector<DrmUUID> NuPlayerDrm::parsePSSH(const void *pssh, size_t psshsize)
diff --git a/media/ndk/NdkMediaCrypto.cpp b/media/ndk/NdkMediaCrypto.cpp
index 792fc00..741e58b 100644
--- a/media/ndk/NdkMediaCrypto.cpp
+++ b/media/ndk/NdkMediaCrypto.cpp
@@ -26,9 +26,8 @@
#include <cutils/properties.h>
#include <utils/Log.h>
#include <utils/StrongPointer.h>
-#include <binder/IServiceManager.h>
+#include <mediadrm/DrmUtils.h>
#include <mediadrm/ICrypto.h>
-#include <mediadrm/IMediaDrmService.h>
#include <android_util_Binder.h>
#include <jni.h>
@@ -36,19 +35,7 @@
using namespace android;
static sp<ICrypto> makeCrypto() {
- sp<IServiceManager> sm = defaultServiceManager();
- sp<IBinder> binder = sm->getService(String16("media.drm"));
-
- sp<IMediaDrmService> service = interface_cast<IMediaDrmService>(binder);
- if (service == NULL) {
- return NULL;
- }
-
- sp<ICrypto> crypto = service->makeCrypto();
- if (crypto == NULL || (crypto->initCheck() != OK && crypto->initCheck() != NO_INIT)) {
- return NULL;
- }
- return crypto;
+ return DrmUtils::MakeCrypto();
}
struct AMediaCrypto {
diff --git a/media/ndk/NdkMediaDrm.cpp b/media/ndk/NdkMediaDrm.cpp
index 842216c..58aa6a3 100644
--- a/media/ndk/NdkMediaDrm.cpp
+++ b/media/ndk/NdkMediaDrm.cpp
@@ -29,6 +29,7 @@
#include <android-base/properties.h>
#include <binder/PermissionController.h>
+#include <mediadrm/DrmUtils.h>
#include <mediadrm/IDrm.h>
#include <mediadrm/IDrmClient.h>
#include <media/stagefright/MediaErrors.h>
@@ -268,19 +269,7 @@
}
static sp<IDrm> CreateDrm() {
- sp<IServiceManager> sm = defaultServiceManager();
- sp<IBinder> binder = sm->getService(String16("media.drm"));
-
- sp<IMediaDrmService> service = interface_cast<IMediaDrmService>(binder);
- if (service == NULL) {
- return NULL;
- }
-
- sp<IDrm> drm = service->makeDrm();
- if (drm == NULL || (drm->initCheck() != OK && drm->initCheck() != NO_INIT)) {
- return NULL;
- }
- return drm;
+ return DrmUtils::MakeDrm();
}