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:
Gene Morgan
2012-09-04 15:52:32 -07:00
committed by Jeff Tinker
parent b092b158d2
commit 8cd5d09119
5 changed files with 114 additions and 20 deletions

View File

@@ -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;

View File

@@ -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()));

View File

@@ -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);