Allow DRM client to pass the FD of an open file to the DRM server.
This allows a DRM client to open a locally-cached file on behalf of the DRM server so the DRM server no longer requires the sdcard_r permission to access the file's metadata. Specifically, this adds an optional attribute FileDescriptorKey to the DrmInfoRequest. This change is dependent on this Widevine CL: https://widevine-internal-review.googlesource.com/#/c/1330/ Relevant bug reports: bug: 6426185 Change-Id: Ia7bcb2455c7a55fa4c7c7061de4d672957c7ac0a
This commit is contained in:
@@ -51,7 +51,7 @@ class WVDRMPluginAPI {
|
||||
virtual bool RegisterDrmInfo(std::string &portal, std::string &dsPath) = 0;
|
||||
virtual bool RegisterDrmInfo(std::string &portal, std::string &dsPath, uint32_t *status) = 0;
|
||||
virtual bool UnregisterDrmInfo(std::string &portal, std::string &dsPath) = 0;
|
||||
virtual bool AcquireDrmInfo(std::string &assetPath, WVCredentials &credentials,
|
||||
virtual bool AcquireDrmInfo(std::string &assetPath, int assetOpenFd, WVCredentials &credentials,
|
||||
std::string &dsPath, const std::string &systemIdStr,
|
||||
const std::string &assetIdStr,
|
||||
const std::string &keyIdStr,
|
||||
@@ -61,10 +61,10 @@ class WVDRMPluginAPI {
|
||||
virtual bool ProcessDrmInfo(std::string &assetPath, int playbackMode) = 0;
|
||||
virtual int CheckRightsStatus(std::string &path) = 0;
|
||||
|
||||
virtual bool GetConstraints(std::string &path, uint32_t *timeSincePlayback,
|
||||
virtual bool GetConstraints(std::string &path, uint32_t *timeSincePlayback,
|
||||
uint32_t *timeRemaining,
|
||||
uint32_t *licenseDuration, std::string &lastError,
|
||||
bool &allowOffline, bool &allowStreaming,
|
||||
bool &allowOffline, bool &allowStreaming,
|
||||
bool &denyHD) = 0;
|
||||
|
||||
virtual bool SetPlaybackStatus(int playbackStatus, off64_t position) = 0;
|
||||
|
||||
@@ -247,6 +247,9 @@ DrmInfo* WVMDrmPlugin::onAcquireDrmInfo(int uniqueId, const DrmInfoRequest* drmI
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// for local files, app may provide the FD of the open file.
|
||||
int assetOpenFd = atol(drmInfoRequest->get(String8("FileDescriptorKey")).string());
|
||||
|
||||
std::string assetDbPath = drmInfoRequest->get(String8("WVAssetDBPathKey")).string();
|
||||
//ALOGV("onAcquireDrmInfo: portal=%s, dsPath=%s", credentials.portal.c_str(), assetDbPath.c_str());
|
||||
|
||||
@@ -262,7 +265,7 @@ DrmInfo* WVMDrmPlugin::onAcquireDrmInfo(int uniqueId, const DrmInfoRequest* drmI
|
||||
|
||||
uint32_t systemId, assetId, keyId;
|
||||
|
||||
if (!mDrmPluginImpl->AcquireDrmInfo(assetPath, credentials, assetDbPath,
|
||||
if (!mDrmPluginImpl->AcquireDrmInfo(assetPath, assetOpenFd, credentials, assetDbPath,
|
||||
systemIdStr, assetIdStr, keyIdStr,
|
||||
&systemId, &assetId, &keyId))
|
||||
return NULL;
|
||||
@@ -277,6 +280,7 @@ DrmInfo* WVMDrmPlugin::onAcquireDrmInfo(int uniqueId, const DrmInfoRequest* drmI
|
||||
DrmBuffer(data, length), drmInfoRequest->getMimeType());
|
||||
|
||||
// Sets additional drmInfo attributes
|
||||
// Do not propagate FileDescriptorKey into the newDrmInfo object
|
||||
drmInfo->put(String8("WVAssetURIKey"), String8(assetPath.c_str()));
|
||||
drmInfo->put(String8("WVDRMServerKey"), String8(credentials.drmServerURL.c_str()));
|
||||
drmInfo->put(String8("WVAssetDbPathKey"), String8(assetDbPath.c_str()));
|
||||
|
||||
@@ -2,6 +2,11 @@
|
||||
* Copyright (C) 2011 Google, Inc. All Rights Reserved
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <dlfcn.h>
|
||||
|
||||
#include <iostream>
|
||||
@@ -21,10 +26,11 @@ public:
|
||||
WVMDrmPluginTest() {}
|
||||
~WVMDrmPluginTest() {}
|
||||
|
||||
void TestAsset(IDrmEngine *plugin, String8 &url);
|
||||
void TestAsset(IDrmEngine *plugin, String8 &url, bool useOpenFd = false);
|
||||
|
||||
void TestRegister(IDrmEngine *plugin);
|
||||
void TestAcquireRights(IDrmEngine *plugin, String8 &url, int playbackMode);
|
||||
void TestAcquireRights(IDrmEngine *plugin, String8 &url, int playbackMode,
|
||||
bool useOpenFd = false);
|
||||
void TestCheckRightsNotAcquired(IDrmEngine *plugin, String8 &url);
|
||||
void TestCheckValidRights(IDrmEngine *plugin, String8 &url);
|
||||
void TestGetConstraints(IDrmEngine *plugin, String8 &url, int playbackMode);
|
||||
@@ -83,10 +89,18 @@ void WVMDrmPluginTest::Run()
|
||||
url = String8("widevine://seawwws001.cdn.shibboleth.tv/videos/content/bbb_ffmpeg_hc_single_480p.wvm");
|
||||
TestAsset(plugin, url);
|
||||
|
||||
// Local asset
|
||||
// Local asset using URL syntax
|
||||
url = String8("file:///sdcard/Widevine/inception_base_360p_single.wvm");
|
||||
TestAsset(plugin, url);
|
||||
|
||||
// Local asset using normal file path
|
||||
url = String8("/sdcard/Widevine/inception_base_360p_single.wvm");
|
||||
TestAsset(plugin, url);
|
||||
|
||||
// Local asset, but also supply open file descriptor
|
||||
url = String8("/sdcard/Widevine/inception_base_360p_single.wvm");
|
||||
TestAsset(plugin, url, true);
|
||||
|
||||
// Remote asset with query parameters
|
||||
url = String8("http://seawwws001.cdn.shibboleth.tv/videos/content/bbb_ffmpeg_hc_single_480p.wvm?a=b");
|
||||
TestAsset(plugin, url);
|
||||
@@ -118,15 +132,32 @@ void WVMDrmPluginTest::TestRegister(IDrmEngine *plugin)
|
||||
delete info;
|
||||
}
|
||||
|
||||
void WVMDrmPluginTest::TestAcquireRights(IDrmEngine *plugin, String8 &url, int playbackMode)
|
||||
void WVMDrmPluginTest::TestAcquireRights(IDrmEngine *plugin, String8 &url,
|
||||
int playbackMode, bool useOpenFd)
|
||||
{
|
||||
cout << "WVDrmPluginTest::TestAcquireRights url=" << url << " mode=" << playbackMode << endl;
|
||||
cout << "WVDrmPluginTest::TestAcquireRights url=" << url << " mode=" <<
|
||||
playbackMode << " useOpenFd=" << useOpenFd << endl;
|
||||
|
||||
int openFd = -1;
|
||||
|
||||
String8 mimeType("video/wvm");
|
||||
DrmInfoRequest rightsAcquisitionInfo(DrmInfoRequest::TYPE_RIGHTS_ACQUISITION_INFO, mimeType);
|
||||
rightsAcquisitionInfo.put(String8("WVDRMServerKey"), String8(
|
||||
"https://staging.shibboleth.tv/widevine/cypherpc/cgi-bin/GetEMMs.cgi"));
|
||||
rightsAcquisitionInfo.put(String8("WVAssetURIKey"), url);
|
||||
|
||||
if (useOpenFd) {
|
||||
char openFdStr[16];
|
||||
openFd = open(url.string(), O_RDONLY);
|
||||
if (openFd == -1) {
|
||||
cout << "error opening " << url << ":" << endl;
|
||||
fprintf(stderr, "Couldn't open local asset file\n");
|
||||
exit(-1);
|
||||
}
|
||||
sprintf(openFdStr, "%lu", (unsigned long)openFd);
|
||||
rightsAcquisitionInfo.put(String8("FileDescriptorKey"), String8(openFdStr));
|
||||
}
|
||||
|
||||
rightsAcquisitionInfo.put(String8("WVDeviceIDKey"), String8("device1234"));
|
||||
rightsAcquisitionInfo.put(String8("WVPortalKey"), String8("OEM"));
|
||||
if (playbackMode) {
|
||||
@@ -142,6 +173,10 @@ void WVMDrmPluginTest::TestAcquireRights(IDrmEngine *plugin, String8 &url, int p
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
if (useOpenFd && (openFd != -1)) {
|
||||
close(openFd);
|
||||
}
|
||||
|
||||
DrmInfoStatus *status = plugin->processDrmInfo(0, info);
|
||||
if (status == NULL || status->statusCode != DrmInfoStatus::STATUS_OK) {
|
||||
fprintf(stderr, "processDrmInfo failed!\n");
|
||||
@@ -260,33 +295,35 @@ void WVMDrmPluginTest::TestRemoveAllRights(IDrmEngine *plugin)
|
||||
}
|
||||
}
|
||||
|
||||
void WVMDrmPluginTest::TestAsset(IDrmEngine *plugin, String8 &url)
|
||||
void WVMDrmPluginTest::TestAsset(IDrmEngine *plugin, String8 &url,
|
||||
bool useOpenFd)
|
||||
{
|
||||
cout << "WVDrmPluginTest::TestAsset url=" << url << endl;
|
||||
cout << "WVDrmPluginTest::TestAsset url=" << url <<
|
||||
" useOpenFd=" << useOpenFd << endl;
|
||||
|
||||
TestRegister(plugin);
|
||||
TestRemoveAllRights(plugin);
|
||||
TestCheckRightsNotAcquired(plugin, url);
|
||||
|
||||
TestAcquireRights(plugin, url, PlaybackMode_Default);
|
||||
TestAcquireRights(plugin, url, PlaybackMode_Default, useOpenFd);
|
||||
TestCheckValidRights(plugin, url);
|
||||
TestGetConstraints(plugin, url, PlaybackMode_Any);
|
||||
TestRemoveRights(plugin, url);
|
||||
TestCheckRightsNotAcquired(plugin, url);
|
||||
|
||||
TestAcquireRights(plugin, url, PlaybackMode_Offline);
|
||||
TestAcquireRights(plugin, url, PlaybackMode_Offline, useOpenFd);
|
||||
TestCheckValidRights(plugin, url);
|
||||
TestGetConstraints(plugin, url, PlaybackMode_Offline);
|
||||
TestRemoveRights(plugin, url);
|
||||
TestCheckRightsNotAcquired(plugin, url);
|
||||
|
||||
TestAcquireRights(plugin, url, PlaybackMode_Streaming);
|
||||
TestAcquireRights(plugin, url, PlaybackMode_Streaming, useOpenFd);
|
||||
TestCheckValidRights(plugin, url);
|
||||
TestGetConstraints(plugin, url, PlaybackMode_Streaming);
|
||||
TestRemoveRights(plugin, url);
|
||||
TestCheckRightsNotAcquired(plugin, url);
|
||||
|
||||
TestAcquireRights(plugin, url, PlaybackMode_Any);
|
||||
TestAcquireRights(plugin, url, PlaybackMode_Any, useOpenFd);
|
||||
TestCheckValidRights(plugin, url);
|
||||
TestGetConstraints(plugin, url, PlaybackMode_Any);
|
||||
TestRemoveRights(plugin, url);
|
||||
|
||||
Reference in New Issue
Block a user