Merge "Allow metrics history to outlive the Android CDM." into udc-dev

This commit is contained in:
Alex Dale
2023-04-29 00:17:49 +00:00
committed by Android (Google) Code Review
3 changed files with 91 additions and 11 deletions

View File

@@ -52,9 +52,39 @@ class WvMetricsSnapshot {
::time_t timestamp_ = 0;
};
class WvMetricsSnapshotQueue
: public android::LightRefBase<WvMetricsSnapshotQueue> {
public:
WvMetricsSnapshotQueue();
explicit WvMetricsSnapshotQueue(size_t capacity) : capacity_(capacity) {}
size_t capacity() const { return capacity_; }
size_t size() const { return snapshots_.size(); }
WvMetricsSnapshotQueue(const WvMetricsSnapshotQueue&) = delete;
WvMetricsSnapshotQueue(WvMetricsSnapshotQueue&&) = delete;
WvMetricsSnapshotQueue& operator=(const WvMetricsSnapshotQueue&) = delete;
WvMetricsSnapshotQueue& operator=(WvMetricsSnapshotQueue&&) = delete;
void PushMetrics(WvMetricsSnapshot&& snapshot);
void PushMetrics(const WvMetricsSnapshot& snapshot);
bool GetAll(std::vector<WvMetricsSnapshot>* snapshots) const;
void Clear();
private:
void ReFit();
const size_t capacity_;
mutable std::mutex mutex_;
std::deque<WvMetricsSnapshot> snapshots_;
};
class WvContentDecryptionModule : public android::RefBase, public TimerHandler {
public:
WvContentDecryptionModule();
explicit WvContentDecryptionModule(WvMetricsSnapshotQueue* metrics_queue);
virtual ~WvContentDecryptionModule();
// Static methods
@@ -308,7 +338,8 @@ class WvContentDecryptionModule : public android::RefBase, public TimerHandler {
// Contains a finite list of histories of different CDM engine instances.
// When a CDM engine is closed, its metrics will be saved.
std::deque<WvMetricsSnapshot> saved_metrics_snapshots_;
// Only used if not null.
WvMetricsSnapshotQueue* saved_metrics_snapshots_ = nullptr;
CORE_DISALLOW_COPY_AND_ASSIGN(WvContentDecryptionModule);
};

View File

@@ -86,10 +86,48 @@ std::string WvMetricsSnapshot::GetFormattedTimestamp() const {
return result;
}
WvMetricsSnapshotQueue::WvMetricsSnapshotQueue()
: capacity_(kMaxSavedMetricsSnapshotCount) {}
void WvMetricsSnapshotQueue::PushMetrics(WvMetricsSnapshot&& snapshot) {
std::unique_lock<std::mutex> lock(mutex_);
snapshots_.push_front(std::move(snapshot));
ReFit();
}
void WvMetricsSnapshotQueue::PushMetrics(const WvMetricsSnapshot& snapshot) {
std::unique_lock<std::mutex> lock(mutex_);
snapshots_.push_front(snapshot);
ReFit();
}
bool WvMetricsSnapshotQueue::GetAll(
std::vector<WvMetricsSnapshot>* snapshots) const {
if (snapshots == nullptr) return false;
std::unique_lock<std::mutex> lock(mutex_);
snapshots->assign(snapshots_.begin(), snapshots_.end());
return true;
}
void WvMetricsSnapshotQueue::Clear() {
std::unique_lock<std::mutex> lock(mutex_);
snapshots_.clear();
}
void WvMetricsSnapshotQueue::ReFit() {
if (capacity_ > 0 && snapshots_.size() > capacity_) {
snapshots_.resize(capacity_);
}
}
std::mutex WvContentDecryptionModule::session_sharing_id_generation_lock_;
WvContentDecryptionModule::WvContentDecryptionModule() {}
WvContentDecryptionModule::WvContentDecryptionModule(
WvMetricsSnapshotQueue* metrics_queue)
: saved_metrics_snapshots_(metrics_queue) {}
WvContentDecryptionModule::~WvContentDecryptionModule() {
CryptoSession::DisableDelayedTermination();
CloseAllCdms();
@@ -497,11 +535,16 @@ CdmResponseType WvContentDecryptionModule::GetAllSavedMetricsSnapshots(
if (snapshots == nullptr) {
return CdmResponseType(PARAMETER_NULL);
}
std::unique_lock<std::mutex> auto_lock(cdms_lock_);
if (saved_metrics_snapshots_ == nullptr) {
snapshots->clear();
// Storing the metrics might not be available in some cases.
return CdmResponseType(NO_ERROR);
}
// This has the potential to be an expensive operation. However,
// this function is only used during debug reporting.
snapshots->assign(saved_metrics_snapshots_.cbegin(),
saved_metrics_snapshots_.cend());
if (!saved_metrics_snapshots_->GetAll(snapshots)) {
return CdmResponseType(UNKNOWN_ERROR);
}
return CdmResponseType(NO_ERROR);
}
@@ -521,12 +564,9 @@ CdmResponseType WvContentDecryptionModule::GetCurrentMetricsInternal(
void WvContentDecryptionModule::SaveMetrics(
const CdmIdentifier& identifier, drm_metrics::WvCdmMetrics&& metrics) {
// Caller should have acquired |cdms_lock_|.
saved_metrics_snapshots_.push_front(
if (saved_metrics_snapshots_ == nullptr) return;
saved_metrics_snapshots_->PushMetrics(
WvMetricsSnapshot::MakeSnapshot(identifier, std::move(metrics)));
if (saved_metrics_snapshots_.size() > kMaxSavedMetricsSnapshotCount) {
saved_metrics_snapshots_.resize(kMaxSavedMetricsSnapshotCount);
}
}
WvContentDecryptionModule::CdmInfo::CdmInfo()

View File

@@ -15,12 +15,16 @@
namespace wvdrm {
using wvcdm::WvContentDecryptionModule;
using android::Mutex;
using android::sp;
using android::wp;
using wvcdm::WvContentDecryptionModule;
using wvcdm::WvMetricsSnapshotQueue;
Mutex cdmLock;
// TODO(b/270166158): Make this a loadable/storable when provided
// a special debug property.
sp<WvMetricsSnapshotQueue> sMetricsQueue;
// The strong pointers that keep this object alive live in the plugin objects.
// If all the plugins are deleted, the CDM will be deleted, and subsequent
// invocations of this code will construct a new CDM.
@@ -29,11 +33,16 @@ wp<WvContentDecryptionModule> sCdm;
sp<WvContentDecryptionModule> getCDM() {
Mutex::Autolock lock(cdmLock); // This function is a critical section.
if (sMetricsQueue == nullptr) {
ALOGD("Instantiating CDM metrics queue");
sMetricsQueue = new WvMetricsSnapshotQueue();
}
sp<WvContentDecryptionModule> cdm = sCdm.promote();
if (cdm == NULL) {
ALOGD("Instantiating CDM.");
cdm = new WvContentDecryptionModule();
cdm = new WvContentDecryptionModule(sMetricsQueue.get());
sCdm = cdm;
}