Merge of usage reporting and license changes from WV CDM repo

* CdmSession unittest and license request time changes
  b/15914199
  Merge of https://widevine-internal-review.googlesource.com/#/c/10597/

* Specify OEMCrypto API version in client capabilities
  b/15388863
  Merge of https://widevine-internal-review.googlesource.com/#/c/10616/

* Report start and last play time in license request
  b/15995227
  Merge of https://widevine-internal-review.googlesource.com/#/c/10617/

* Respect can_play flag
  b/15330338
  Merge of https://widevine-internal-review.googlesource.com/#/c/10619/

* Restore offline session information
  b/16009274
  Merge of https://widevine-internal-review.googlesource.com/#/c/10641/

Change-Id: I17fdc309efbc1d44385a86a368df11b1349b29c2
This commit is contained in:
Rahul Frias
2014-07-02 13:03:09 -07:00
parent 9b4da994ec
commit 7a933ee48e
18 changed files with 1308 additions and 692 deletions

View File

@@ -31,11 +31,6 @@ class CdmSession {
virtual CdmResponseType RestoreUsageSession(
const CdmKeyMessage& key_request, const CdmKeyResponse& key_response);
virtual void set_key_system(const CdmKeySystem& ksystem) {
key_system_ = ksystem;
}
virtual const CdmKeySystem& key_system() { return key_system_; }
virtual const CdmSessionId& session_id() { return session_id_; }
virtual CdmResponseType GenerateKeyRequest(
@@ -85,7 +80,7 @@ class CdmSession {
virtual bool AttachEventListener(WvCdmEventListener* listener);
virtual bool DetachEventListener(WvCdmEventListener* listener);
virtual void OnTimerEvent();
virtual void OnTimerEvent(bool update_usage);
virtual void OnKeyReleaseEvent(const CdmKeySetId& key_set_id);
virtual SecurityLevel GetRequestedSecurityLevel();
@@ -99,6 +94,11 @@ class CdmSession {
}
private:
// Internal constructor
void Create(CdmLicense* license_parser, CryptoSession* crypto_session,
PolicyEngine* policy_engine, DeviceFiles* file_handle,
const CdmClientPropertySet* cdm_client_property_set);
// Generate unique ID for each new session.
CdmSessionId GenerateSessionId();
bool GenerateKeySetId(CdmKeySetId* key_set_id);
@@ -108,16 +108,19 @@ class CdmSession {
bool DeleteLicense();
// instance variables
const CdmSessionId session_id_;
CdmKeySystem key_system_;
CdmLicense license_parser_;
bool initialized_;
CdmSessionId session_id_;
scoped_ptr<CdmLicense> license_parser_;
scoped_ptr<CryptoSession> crypto_session_;
PolicyEngine policy_engine_;
scoped_ptr<PolicyEngine> policy_engine_;
scoped_ptr<DeviceFiles> file_handle_;
bool license_received_;
bool is_offline_;
bool is_release_;
bool is_usage_update_needed_;
bool is_initial_decryption_;
bool has_decrypted_recently_;
CdmSecurityLevel security_level_;
// information useful for offline and usage scenarios
CdmKeyMessage key_request_;
@@ -134,6 +137,16 @@ class CdmSession {
std::set<WvCdmEventListener*> listeners_;
// For testing only
// Takes ownership of license_parser, crypto_session, policy_engine
// and device_files
CdmSession(CdmLicense* license_parser, CryptoSession* crypto_session,
PolicyEngine* policy_engine, DeviceFiles* file_handle,
const CdmClientPropertySet* cdm_client_property_set);
#if defined(UNIT_TEST)
friend class CdmSessionTest;
#endif
CORE_DISALLOW_COPY_AND_ASSIGN(CdmSession);
};

View File

@@ -18,6 +18,24 @@ typedef std::map<CryptoKeyId, CryptoKey*> CryptoKeyMap;
class CryptoSession {
public:
// This enum should be kept in sync with the values specified for
// HDCP capabilities in OEMCryptoCENC.h. (See comments for
// OEMCrypto_GetHDCPCapability)
typedef enum {
kOemCryptoHdcpNotSupported = 0,
kOemCryptoHdcpVersion1 = 1,
kOemCryptoHdcpVersion2 = 2,
kOemCryptoHdcpVersion2_1 = 3,
kOemCryptoHdcpVersion2_2 = 4,
kOemCryptoNoHdcpDeviceAttached = 0xff,
} OemCryptoHdcpVersion;
typedef enum {
kUsageDurationsInvalid = 0,
kUsageDurationPlaybackNotBegun = 1,
kUsageDurationsValid = 2,
} UsageDurationStatus;
CryptoSession();
virtual ~CryptoSession();
@@ -37,7 +55,7 @@ class CryptoSession {
virtual CryptoSessionId oec_session_id() { return oec_session_id_; }
// Key request/response
virtual void GenerateRequestId(std::string& req_id_str);
virtual bool GenerateRequestId(std::string* req_id_str);
virtual bool PrepareRequest(const std::string& key_deriv_message,
bool is_provisioning, std::string* signature);
virtual bool PrepareRenewalRequest(const std::string& message,
@@ -66,13 +84,20 @@ class CryptoSession {
// Media data path
virtual CdmResponseType Decrypt(const CdmDecryptionParameters& parameters);
virtual bool UsageInformationSupport(bool* has_support);
virtual CdmResponseType UpdateUsageInformation();
virtual CdmResponseType DeactivateUsageInformation(
const std::string& provider_session_token);
virtual CdmResponseType GenerateUsageReport(
const std::string& provider_session_token, std::string* usage_report);
const std::string& provider_session_token, std::string* usage_report,
UsageDurationStatus* usage_duration_status,
int64_t* seconds_since_started, int64_t* seconds_since_last_played);
virtual CdmResponseType ReleaseUsageInformation(
const std::string& message, const std::string& signature,
const std::string& provider_session_token);
virtual bool GetHdcpCapabilities(OemCryptoHdcpVersion* current,
OemCryptoHdcpVersion* max);
virtual bool GetRandom(size_t data_length, uint8_t* random_data);
private:

View File

@@ -3,6 +3,7 @@
#ifndef WVCDM_CORE_DEVICE_FILES_H_
#define WVCDM_CORE_DEVICE_FILES_H_
#include "scoped_ptr.h"
#include "wv_cdm_types.h"
#if defined(UNIT_TEST)
@@ -21,11 +22,13 @@ class DeviceFiles {
kLicenseStateUnknown,
} LicenseState;
DeviceFiles(): file_(NULL), security_level_(kSecurityLevelUninitialized),
initialized_(false), test_file_(false) {}
DeviceFiles();
virtual ~DeviceFiles();
virtual bool Init(CdmSecurityLevel security_level);
virtual bool Reset(CdmSecurityLevel security_level) {
return Init(security_level);
}
virtual bool StoreCertificate(const std::string& certificate,
const std::string& wrapped_private_key);
@@ -39,7 +42,9 @@ class DeviceFiles {
const CdmKeyResponse& key_response,
const CdmKeyMessage& key_renewal_request,
const CdmKeyResponse& key_renewal_response,
const std::string& release_server_url);
const std::string& release_server_url,
int64_t playback_start_time,
int64_t last_playback_time);
virtual bool RetrieveLicense(const std::string& key_set_id,
LicenseState* state,
CdmInitData* pssh_data,
@@ -47,7 +52,9 @@ class DeviceFiles {
CdmKeyResponse* key_response,
CdmKeyMessage* key_renewal_request,
CdmKeyResponse* key_renewal_response,
std::string* release_server_url);
std::string* release_server_url,
int64_t* playback_start_time,
int64_t* last_playback_time);
virtual bool DeleteLicense(const std::string& key_set_id);
virtual bool DeleteAllFiles();
virtual bool DeleteAllLicenses();
@@ -93,7 +100,7 @@ class DeviceFiles {
FRIEND_TEST(WvCdmUsageInfoTest, DISABLED_UsageInfo);
#endif
File* file_;
scoped_ptr<File> file_;
CdmSecurityLevel security_level_;
bool initialized_;

View File

@@ -6,6 +6,7 @@
#include <set>
#include "initialization_data.h"
#include "scoped_ptr.h"
#include "wv_cdm_types.h"
namespace video_widevine_server {
@@ -16,14 +17,15 @@ class SignedMessage;
namespace wvcdm {
class Clock;
class CryptoSession;
class PolicyEngine;
class CdmLicense {
public:
CdmLicense() : session_(NULL), initialized_(false) {}
virtual ~CdmLicense() {}
CdmLicense();
virtual ~CdmLicense();
virtual bool Init(const std::string& token, CryptoSession* session,
PolicyEngine* policy_engine);
@@ -42,7 +44,9 @@ class CdmLicense {
virtual bool RestoreOfflineLicense(const CdmKeyMessage& license_request,
const CdmKeyResponse& license_response,
const CdmKeyResponse& license_renewal_response);
const CdmKeyResponse& license_renewal_response,
int64_t playback_start_time,
int64_t last_playback_time);
virtual bool RestoreUsageLicense(const CdmKeyMessage& license_request,
const CdmKeyResponse& license_response);
virtual bool HasInitData() { return !stored_init_data_.empty(); }
@@ -76,6 +80,14 @@ class CdmLicense {
// Used for certificate based licensing
CdmKeyMessage key_request_;
scoped_ptr<Clock> clock_;
// For testing
CdmLicense(Clock* clock);
#if defined(UNIT_TEST)
friend class CdmLicenseTest;
#endif
CORE_DISALLOW_COPY_AND_ASSIGN(CdmLicense);
};

View File

@@ -44,6 +44,7 @@ class PolicyEngine {
// Call this on first decrypt to set the start of playback.
virtual void BeginDecryption(void);
virtual void DecryptionEvent(void);
// UpdateLicense is used in handling a license response for a renewal request.
// The response may only contain any policy fields that have changed. In this
@@ -60,9 +61,21 @@ class PolicyEngine {
bool IsLicenseDurationExpired(int64_t current_time);
bool IsPlaybackDurationExpired(int64_t current_time);
bool GetSecondsSinceStarted(int64_t* seconds_since_started);
bool GetSecondsSinceLastPlayed(int64_t* seconds_since_started);
// for offline save and restore
int64_t GetPlaybackStartTime() { return playback_start_time_; }
int64_t GetLastPlaybackTime() { return last_playback_time_; }
void RestorePlaybackTimes(int64_t playback_start_time,
int64_t last_playback_time);
bool IsLicenseForFuture() { return license_state_ == kLicenseStatePending; }
private:
typedef enum {
kLicenseStateInitial,
kLicenseStatePending, // if license is issued for sometime in the future
kLicenseStateCanPlay,
kLicenseStateNeedRenewal,
kLicenseStateWaitingLicenseUpdate,
@@ -92,18 +105,15 @@ class PolicyEngine {
// from the license server we will get an updated id field.
video_widevine_server::sdk::LicenseIdentification license_id_;
// This is the license start time that gets sent from the server in each
// license request or renewal.
// The server returns the license start time in the license/license renewal
// response based off the request time sent by the client in the
// license request/renewal
int64_t license_start_time_;
// This is the time at which the license was received and playback was
// started. These times are based off the local clock in case there is a
// discrepency between local and server time.
int64_t license_received_time_;
int64_t playback_start_time_;
int64_t last_playback_time_;
// This is used as a reference point for policy management. This value
// represents an offset from license_received_time_. This is used to
// represents an offset from license_start_time_. This is used to
// calculate the time where renewal retries should occur.
int64_t next_renewal_time_;
int64_t policy_max_duration_seconds_;

View File

@@ -87,6 +87,14 @@ class Properties {
security_level_path_backward_compatibility_support_ = flag;
}
#if defined(UNIT_TEST)
FRIEND_TEST(CdmSessionTest, InitWithCertificate);
FRIEND_TEST(CdmSessionTest, InitWithKeybox);
FRIEND_TEST(CdmSessionTest, ReInitFail);
FRIEND_TEST(CdmSessionTest, InitFailCryptoError);
FRIEND_TEST(CdmSessionTest, InitNeedsProvisioning);
#endif
private:
static bool oem_crypto_use_secure_buffers_;
static bool oem_crypto_use_fifo_;