Offline playback for fastball
[ Merge of http://go/wvgerrit/18560 ] This adds support for offline playback. If the content contains mutiple playlists which contain differing EXT-X-KEY attribute lists, each of those keys will need to be saved and restored into separate sessions. b/30041089 Test: Added unit tests to cover new functionality. Some oem_crypto, request_license_test failures but the same as without this CL. Change-Id: Ia1b877e12a67e8a720d29897ac7e2da236090123
This commit is contained in:
@@ -18,13 +18,16 @@
|
||||
#define MD5 CC_MD5
|
||||
#define MD5_DIGEST_LENGTH CC_MD5_DIGEST_LENGTH
|
||||
#else
|
||||
#include <openssl/sha.h>
|
||||
#include <openssl/md5.h>
|
||||
#include <openssl/sha.h>
|
||||
#endif
|
||||
|
||||
// Protobuf generated classes.
|
||||
using video_widevine_client::sdk::DeviceCertificate;
|
||||
using video_widevine_client::sdk::HashedFile;
|
||||
using video_widevine_client::sdk::HlsAttributes;
|
||||
using video_widevine_client::sdk::HlsAttributes_Method_AES_128;
|
||||
using video_widevine_client::sdk::HlsAttributes_Method_SAMPLE_AES;
|
||||
using video_widevine_client::sdk::License;
|
||||
using video_widevine_client::sdk::License_LicenseState_ACTIVE;
|
||||
using video_widevine_client::sdk::License_LicenseState_RELEASING;
|
||||
@@ -298,6 +301,7 @@ bool DeviceFiles::DeleteAllFiles() {
|
||||
|
||||
// We pass an empty string to RemoveFile to delete the device files base
|
||||
// directory itself.
|
||||
// TODO[gmorgan]: verify RemoveFile("") should remove all files.
|
||||
return RemoveFile(kEmptyFileName);
|
||||
}
|
||||
|
||||
@@ -523,6 +527,103 @@ bool DeviceFiles::RetrieveUsageInfoByKeySetId(
|
||||
return false;
|
||||
}
|
||||
|
||||
bool DeviceFiles::StoreHlsAttributes(
|
||||
const std::string& key_set_id, const CdmHlsMethod method,
|
||||
const std::vector<uint8_t>& media_segment_iv) {
|
||||
if (!initialized_) {
|
||||
LOGW("DeviceFiles::StoreHlsAttributes: not initialized");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Fill in file information
|
||||
video_widevine_client::sdk::File file;
|
||||
|
||||
file.set_type(video_widevine_client::sdk::File::HLS_ATTRIBUTES);
|
||||
file.set_version(video_widevine_client::sdk::File::VERSION_1);
|
||||
|
||||
HlsAttributes* hls_attributes = file.mutable_hls_attributes();
|
||||
switch (method) {
|
||||
case kHlsMethodAes128:
|
||||
hls_attributes->set_method(HlsAttributes_Method_AES_128);
|
||||
break;
|
||||
case kHlsMethodSampleAes:
|
||||
hls_attributes->set_method(HlsAttributes_Method_SAMPLE_AES);
|
||||
break;
|
||||
case kHlsMethodNone:
|
||||
default:
|
||||
LOGW("DeviceFiles::StoreHlsAttributeInfo: Unknown HLS method: %u",
|
||||
method);
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
hls_attributes->set_media_segment_iv(&media_segment_iv[0],
|
||||
media_segment_iv.size());
|
||||
|
||||
std::string serialized_file;
|
||||
file.SerializeToString(&serialized_file);
|
||||
|
||||
return StoreFileWithHash(key_set_id + kHlsAttributesFileNameExt,
|
||||
serialized_file);
|
||||
}
|
||||
|
||||
bool DeviceFiles::RetrieveHlsAttributes(
|
||||
const std::string& key_set_id, CdmHlsMethod* method,
|
||||
std::vector<uint8_t>* media_segment_iv) {
|
||||
if (!initialized_) {
|
||||
LOGW("DeviceFiles::RetrieveHlsAttributes: not initialized");
|
||||
return false;
|
||||
}
|
||||
|
||||
video_widevine_client::sdk::File file;
|
||||
if (!RetrieveHashedFile(key_set_id + kHlsAttributesFileNameExt, &file)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (file.type() != video_widevine_client::sdk::File::HLS_ATTRIBUTES) {
|
||||
LOGW("DeviceFiles::RetrieveHlsAttributes: Incorrect file type: %u",
|
||||
file.type());
|
||||
return false;
|
||||
}
|
||||
|
||||
if (file.version() != video_widevine_client::sdk::File::VERSION_1) {
|
||||
LOGW("DeviceFiles::RetrieveHlsAttributes: Incorrect file version: %u",
|
||||
file.version());
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!file.has_hls_attributes()) {
|
||||
LOGW("DeviceFiles::RetrieveHlsAttributes: HLS attributes not present");
|
||||
return false;
|
||||
}
|
||||
|
||||
HlsAttributes attributes = file.hls_attributes();
|
||||
|
||||
switch (attributes.method()) {
|
||||
case HlsAttributes_Method_AES_128:
|
||||
*method = kHlsMethodAes128;
|
||||
break;
|
||||
case HlsAttributes_Method_SAMPLE_AES:
|
||||
*method = kHlsMethodSampleAes;
|
||||
break;
|
||||
default:
|
||||
LOGW("DeviceFiles::RetrieveHlsAttributes: Unrecognized HLS method: %u",
|
||||
attributes.method());
|
||||
*method = kHlsMethodNone;
|
||||
break;
|
||||
}
|
||||
media_segment_iv->assign(attributes.media_segment_iv().begin(),
|
||||
attributes.media_segment_iv().end());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DeviceFiles::DeleteHlsAttributes(const std::string& key_set_id) {
|
||||
if (!initialized_) {
|
||||
LOGW("DeviceFiles::DeleteHlsAttributes: not initialized");
|
||||
return false;
|
||||
}
|
||||
return RemoveFile(key_set_id + kHlsAttributesFileNameExt);
|
||||
}
|
||||
|
||||
bool DeviceFiles::StoreFileWithHash(const std::string& name,
|
||||
const std::string& serialized_file) {
|
||||
// calculate SHA hash
|
||||
@@ -691,6 +792,10 @@ std::string DeviceFiles::GetCertificateFileName() {
|
||||
return kCertificateFileName;
|
||||
}
|
||||
|
||||
std::string DeviceFiles::GetHlsAttributesFileNameExtension() {
|
||||
return kHlsAttributesFileNameExt;
|
||||
}
|
||||
|
||||
std::string DeviceFiles::GetLicenseFileNameExtension() {
|
||||
return kLicenseFileNameExt;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user