Commit e4b00999 authored by Jeffrey Kardatzke's avatar Jeffrey Kardatzke Committed by Chromium LUCI CQ

Add UMA stats for ChromeOS platform CDM

This adds UMA stats for the following:
1. Selection between Chrome CDM and platform CDM (Beanstalk)
2. System codes for rejected promises from platform CDM (to distinguish
these from the same errors w/ a browser CDM)
3. Status for output protection query/result (to distinguish these from
the same data w/ browser CDM)

BUG=b:153111783
TEST=Builds and runs, histogram presubmits pass

Change-Id: I7a51b49594b6ac36500b52d602252bdd29b4c1d0
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2597899
Auto-Submit: Jeffrey Kardatzke <jkardatzke@google.com>
Commit-Queue: J Kardatzke <jkardatzke@chromium.org>
Reviewed-by: default avatarSteven Holte <holte@chromium.org>
Reviewed-by: default avatarXiaohan Wang <xhwang@chromium.org>
Cr-Commit-Position: refs/heads/master@{#839657}
parent 45a663ed
......@@ -8,6 +8,7 @@
#include "base/bind.h"
#include "base/memory/scoped_refptr.h"
#include "base/metrics/histogram_functions.h"
#include "base/time/time.h"
#include "media/base/cdm_promise.h"
#include "media/base/decoder_buffer.h"
......@@ -91,6 +92,10 @@ void RejectPromiseConnectionLost(std::unique_ptr<media::CdmPromise> promise) {
"Mojo connection lost");
}
void ReportSystemCodeUMA(uint32_t system_code) {
base::UmaHistogramSparse("Media.EME.CrosPlatformCdm.SystemCode", system_code);
}
} // namespace
namespace chromeos {
......@@ -539,6 +544,7 @@ void ContentDecryptionModuleAdapter::OnConnectionError() {
void ContentDecryptionModuleAdapter::RejectTrackedPromise(
uint32_t promise_id,
cdm::mojom::CdmPromiseResultPtr promise_result) {
ReportSystemCodeUMA(promise_result->system_code);
cdm_promise_adapter_.RejectPromise(promise_id, promise_result->exception,
promise_result->system_code,
promise_result->error_message);
......
......@@ -9,6 +9,8 @@
#include "ash/shell.h"
#include "base/bind.h"
#include "base/callback_helpers.h"
#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "mojo/public/cpp/bindings/self_owned_receiver.h"
......@@ -129,6 +131,19 @@ class DisplaySystemDelegateImpl
display::DisplayConfigurator* display_configurator_; // Not owned.
};
// These are reported to UMA server. Do not renumber or reuse values.
enum class OutputProtectionStatus {
kQueried = 0,
kNoExternalLink = 1,
kAllExternalLinksProtected = 2,
// Note: Only add new values immediately before this line.
kMaxValue = kAllExternalLinksProtected,
};
void ReportOutputProtectionUMA(OutputProtectionStatus status) {
UMA_HISTOGRAM_ENUMERATION("Media.EME.OutputProtection.PlatformCdm", status);
}
} // namespace
// static
......@@ -175,6 +190,8 @@ void OutputProtectionImpl::QueryStatus(QueryStatusCallback callback) {
return;
}
ReportOutputProtectionQuery();
// We want to copy this since we will manipulate it.
std::vector<int64_t> remaining_displays = display_id_list_;
int64_t curr_display_id = remaining_displays.back();
......@@ -286,6 +303,11 @@ void OutputProtectionImpl::QueryStatusCallbackAggregator(
return;
}
if (aggregate_success) {
ReportOutputProtectionQueryResult(aggregate_link_mask,
aggregate_protection_mask);
}
aggregate_protection_mask &= ~aggregate_no_protection_mask;
std::move(callback).Run(aggregate_success, aggregate_link_mask,
ConvertProtection(aggregate_protection_mask));
......@@ -316,4 +338,48 @@ void OutputProtectionImpl::OnDisplayRemoved(const display::Display& display) {
HandleDisplayChange();
}
void OutputProtectionImpl::ReportOutputProtectionQuery() {
if (uma_for_output_protection_query_reported_)
return;
ReportOutputProtectionUMA(OutputProtectionStatus::kQueried);
uma_for_output_protection_query_reported_ = true;
}
void OutputProtectionImpl::ReportOutputProtectionQueryResult(
uint32_t link_mask,
uint32_t protection_mask) {
DCHECK(uma_for_output_protection_query_reported_);
if (uma_for_output_protection_positive_result_reported_)
return;
// Report UMAs for output protection query result.
uint32_t external_links =
(link_mask & ~display::DISPLAY_CONNECTION_TYPE_INTERNAL);
if (!external_links) {
ReportOutputProtectionUMA(OutputProtectionStatus::kNoExternalLink);
uma_for_output_protection_positive_result_reported_ = true;
return;
}
bool is_unprotectable_link_connected =
(external_links & ~kProtectableConnectionTypes) != 0;
bool is_hdcp_enabled_on_all_protectable_links =
(protection_mask & desired_protection_mask_) != 0;
if (!is_unprotectable_link_connected &&
is_hdcp_enabled_on_all_protectable_links) {
ReportOutputProtectionUMA(
OutputProtectionStatus::kAllExternalLinksProtected);
uma_for_output_protection_positive_result_reported_ = true;
return;
}
// Do not report a negative result because it could be a false negative.
// Instead, we will calculate number of negatives using the total number of
// queries and positive results.
}
} // namespace chromeos
......@@ -105,6 +105,11 @@ class COMPONENT_EXPORT(CDM_FACTORY_DAEMON) OutputProtectionImpl
uint32_t changed_metrics) override;
void OnDisplayRemoved(const display::Display& display) override;
// Helper methods to report output protection UMAs.
void ReportOutputProtectionQuery();
void ReportOutputProtectionQueryResult(uint32_t link_mask,
uint32_t protection_mask);
std::unique_ptr<DisplaySystemDelegate> delegate_;
display::ContentProtectionManager::ClientId client_id_;
......@@ -112,6 +117,11 @@ class COMPONENT_EXPORT(CDM_FACTORY_DAEMON) OutputProtectionImpl
uint32_t desired_protection_mask_{0};
// Tracks whether an output protection query and a positive query result (no
// unprotected external link) have been reported to UMA.
bool uma_for_output_protection_query_reported_ = false;
bool uma_for_output_protection_positive_result_reported_ = false;
// WeakPtrFactory to use for callbacks.
base::WeakPtrFactory<OutputProtectionImpl> weak_factory_{this};
};
......
......@@ -233,6 +233,18 @@ class SeatbeltExtensionTokenProviderImpl
#if BUILDFLAG(ENABLE_LIBRARY_CDMS) && BUILDFLAG(IS_CHROMEOS_ASH)
constexpr char kChromeOsCdmFileSystemId[] =
"application_chromeos-cdm-factory-daemon";
// These are reported to UMA server. Do not renumber or reuse values.
enum class CrosCdmType {
kChromeCdm = 0,
kPlatformCdm = 1,
// Note: Only add new values immediately before this line.
kMaxValue = kPlatformCdm,
};
void ReportCdmTypeUMA(CrosCdmType cdm_type) {
UMA_HISTOGRAM_ENUMERATION("Media.EME.CrosCdmType", cdm_type);
}
#endif // BUILDFLAG(ENABLE_LIBRARY_CDMS) && BUILDFLAG(IS_CHROMEOS_ASH)
// The amount of time to allow the secondary Media Service instance to idle
......@@ -455,6 +467,7 @@ void MediaInterfaceProxy::CreateCdm(const std::string& key_system,
return;
}
}
ReportCdmTypeUMA(CrosCdmType::kChromeCdm);
#endif // BUILDFLAG(IS_CHROMEOS_ASH)
auto* factory = GetCdmFactory(key_system);
#elif BUILDFLAG(ENABLE_CAST_RENDERER)
......@@ -577,6 +590,7 @@ void MediaInterfaceProxy::OnChromeOsCdmCreated(
mojo::PendingRemote<media::mojom::Decryptor> decryptor,
const std::string& error_message) {
if (receiver) {
ReportCdmTypeUMA(CrosCdmType::kPlatformCdm);
// Success case, just pass it back through the callback.
std::move(callback).Run(std::move(receiver), cdm_id, std::move(decryptor),
error_message);
......@@ -592,6 +606,7 @@ void MediaInterfaceProxy::OnChromeOsCdmCreated(
mojo::NullRemote(), "Unable to find a CDM factory");
return;
}
ReportCdmTypeUMA(CrosCdmType::kChromeCdm);
factory->CreateCdm(key_system, cdm_config, std::move(callback));
}
#endif // BUILDFLAG(IS_CHROMEOS_ASH)
......
......@@ -14251,6 +14251,11 @@ to ensure that the crash string is shown properly on the user-facing crash UI.
<int value="3" label="User disabled"/>
</enum>
<enum name="CrosCdmType">
<int value="0" label="Chrome CDM"/>
<int value="1" label="Platform CDM"/>
</enum>
<enum name="CrosComponentManagerError">
<int value="0" label="NONE"/>
<int value="1" label="UNKNOWN_COMPONENT"/>
......@@ -1513,6 +1513,25 @@ reviews. Googlers can read more about this at go/gwsq-gerrit.
<summary>The time it takes to create the CDM instance.</summary>
</histogram>
<histogram name="Media.EME.CrosCdmType" enum="CrosCdmType"
expires_after="2022-01-15">
<owner>jkardatzke@chromium.org</owner>
<owner>cros-gfx-video@google.com</owner>
<summary>
Whether we used the platform CDM on Chrome OS that includes HW secure
Widevine support, or fell back to the Chrome SW CDM.
</summary>
</histogram>
<histogram name="Media.EME.CrosPlatformCdm.SystemCode" enum="CdmSystemCode"
expires_after="2022-01-15">
<owner>jkardatzke@chromium.org</owner>
<owner>cros-gfx-video@google.com</owner>
<summary>
System code count in promise rejection for ChromeOS platform CDM.
</summary>
</histogram>
<histogram name="Media.EME.EncryptedEvent" enum="BooleanEncryptedEvent"
expires_after="2021-05-07">
<owner>xhwang@chromium.org</owner>
......@@ -1674,6 +1693,16 @@ reviews. Googlers can read more about this at go/gwsq-gerrit.
</summary>
</histogram>
<histogram name="Media.EME.OutputProtection.PlatformCdm"
enum="MediaOutputProtectionStatus" expires_after="2022-01-15">
<owner>jkardatzke@chromium.org</owner>
<owner>cros-gfx-video@google.com</owner>
<summary>
Output protection query status and result. One query and one positive (no
unprotected external links) result (if any) are reported per CDM instance.
</summary>
</histogram>
<histogram name="Media.EME.RequestMediaKeySystemAccess"
enum="RequestMediaKeySystemAccessStatus" expires_after="2021-06-20">
<owner>sandersd@chromium.org</owner>
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment