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 @@ ...@@ -8,6 +8,7 @@
#include "base/bind.h" #include "base/bind.h"
#include "base/memory/scoped_refptr.h" #include "base/memory/scoped_refptr.h"
#include "base/metrics/histogram_functions.h"
#include "base/time/time.h" #include "base/time/time.h"
#include "media/base/cdm_promise.h" #include "media/base/cdm_promise.h"
#include "media/base/decoder_buffer.h" #include "media/base/decoder_buffer.h"
...@@ -91,6 +92,10 @@ void RejectPromiseConnectionLost(std::unique_ptr<media::CdmPromise> promise) { ...@@ -91,6 +92,10 @@ void RejectPromiseConnectionLost(std::unique_ptr<media::CdmPromise> promise) {
"Mojo connection lost"); "Mojo connection lost");
} }
void ReportSystemCodeUMA(uint32_t system_code) {
base::UmaHistogramSparse("Media.EME.CrosPlatformCdm.SystemCode", system_code);
}
} // namespace } // namespace
namespace chromeos { namespace chromeos {
...@@ -539,6 +544,7 @@ void ContentDecryptionModuleAdapter::OnConnectionError() { ...@@ -539,6 +544,7 @@ void ContentDecryptionModuleAdapter::OnConnectionError() {
void ContentDecryptionModuleAdapter::RejectTrackedPromise( void ContentDecryptionModuleAdapter::RejectTrackedPromise(
uint32_t promise_id, uint32_t promise_id,
cdm::mojom::CdmPromiseResultPtr promise_result) { cdm::mojom::CdmPromiseResultPtr promise_result) {
ReportSystemCodeUMA(promise_result->system_code);
cdm_promise_adapter_.RejectPromise(promise_id, promise_result->exception, cdm_promise_adapter_.RejectPromise(promise_id, promise_result->exception,
promise_result->system_code, promise_result->system_code,
promise_result->error_message); promise_result->error_message);
......
...@@ -9,6 +9,8 @@ ...@@ -9,6 +9,8 @@
#include "ash/shell.h" #include "ash/shell.h"
#include "base/bind.h" #include "base/bind.h"
#include "base/callback_helpers.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_task_traits.h"
#include "content/public/browser/browser_thread.h" #include "content/public/browser/browser_thread.h"
#include "mojo/public/cpp/bindings/self_owned_receiver.h" #include "mojo/public/cpp/bindings/self_owned_receiver.h"
...@@ -129,6 +131,19 @@ class DisplaySystemDelegateImpl ...@@ -129,6 +131,19 @@ class DisplaySystemDelegateImpl
display::DisplayConfigurator* display_configurator_; // Not owned. 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 } // namespace
// static // static
...@@ -175,6 +190,8 @@ void OutputProtectionImpl::QueryStatus(QueryStatusCallback callback) { ...@@ -175,6 +190,8 @@ void OutputProtectionImpl::QueryStatus(QueryStatusCallback callback) {
return; return;
} }
ReportOutputProtectionQuery();
// We want to copy this since we will manipulate it. // We want to copy this since we will manipulate it.
std::vector<int64_t> remaining_displays = display_id_list_; std::vector<int64_t> remaining_displays = display_id_list_;
int64_t curr_display_id = remaining_displays.back(); int64_t curr_display_id = remaining_displays.back();
...@@ -286,6 +303,11 @@ void OutputProtectionImpl::QueryStatusCallbackAggregator( ...@@ -286,6 +303,11 @@ void OutputProtectionImpl::QueryStatusCallbackAggregator(
return; return;
} }
if (aggregate_success) {
ReportOutputProtectionQueryResult(aggregate_link_mask,
aggregate_protection_mask);
}
aggregate_protection_mask &= ~aggregate_no_protection_mask; aggregate_protection_mask &= ~aggregate_no_protection_mask;
std::move(callback).Run(aggregate_success, aggregate_link_mask, std::move(callback).Run(aggregate_success, aggregate_link_mask,
ConvertProtection(aggregate_protection_mask)); ConvertProtection(aggregate_protection_mask));
...@@ -316,4 +338,48 @@ void OutputProtectionImpl::OnDisplayRemoved(const display::Display& display) { ...@@ -316,4 +338,48 @@ void OutputProtectionImpl::OnDisplayRemoved(const display::Display& display) {
HandleDisplayChange(); 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 } // namespace chromeos
...@@ -105,6 +105,11 @@ class COMPONENT_EXPORT(CDM_FACTORY_DAEMON) OutputProtectionImpl ...@@ -105,6 +105,11 @@ class COMPONENT_EXPORT(CDM_FACTORY_DAEMON) OutputProtectionImpl
uint32_t changed_metrics) override; uint32_t changed_metrics) override;
void OnDisplayRemoved(const display::Display& display) 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_; std::unique_ptr<DisplaySystemDelegate> delegate_;
display::ContentProtectionManager::ClientId client_id_; display::ContentProtectionManager::ClientId client_id_;
...@@ -112,6 +117,11 @@ class COMPONENT_EXPORT(CDM_FACTORY_DAEMON) OutputProtectionImpl ...@@ -112,6 +117,11 @@ class COMPONENT_EXPORT(CDM_FACTORY_DAEMON) OutputProtectionImpl
uint32_t desired_protection_mask_{0}; 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. // WeakPtrFactory to use for callbacks.
base::WeakPtrFactory<OutputProtectionImpl> weak_factory_{this}; base::WeakPtrFactory<OutputProtectionImpl> weak_factory_{this};
}; };
......
...@@ -233,6 +233,18 @@ class SeatbeltExtensionTokenProviderImpl ...@@ -233,6 +233,18 @@ class SeatbeltExtensionTokenProviderImpl
#if BUILDFLAG(ENABLE_LIBRARY_CDMS) && BUILDFLAG(IS_CHROMEOS_ASH) #if BUILDFLAG(ENABLE_LIBRARY_CDMS) && BUILDFLAG(IS_CHROMEOS_ASH)
constexpr char kChromeOsCdmFileSystemId[] = constexpr char kChromeOsCdmFileSystemId[] =
"application_chromeos-cdm-factory-daemon"; "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) #endif // BUILDFLAG(ENABLE_LIBRARY_CDMS) && BUILDFLAG(IS_CHROMEOS_ASH)
// The amount of time to allow the secondary Media Service instance to idle // 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, ...@@ -455,6 +467,7 @@ void MediaInterfaceProxy::CreateCdm(const std::string& key_system,
return; return;
} }
} }
ReportCdmTypeUMA(CrosCdmType::kChromeCdm);
#endif // BUILDFLAG(IS_CHROMEOS_ASH) #endif // BUILDFLAG(IS_CHROMEOS_ASH)
auto* factory = GetCdmFactory(key_system); auto* factory = GetCdmFactory(key_system);
#elif BUILDFLAG(ENABLE_CAST_RENDERER) #elif BUILDFLAG(ENABLE_CAST_RENDERER)
...@@ -577,6 +590,7 @@ void MediaInterfaceProxy::OnChromeOsCdmCreated( ...@@ -577,6 +590,7 @@ void MediaInterfaceProxy::OnChromeOsCdmCreated(
mojo::PendingRemote<media::mojom::Decryptor> decryptor, mojo::PendingRemote<media::mojom::Decryptor> decryptor,
const std::string& error_message) { const std::string& error_message) {
if (receiver) { if (receiver) {
ReportCdmTypeUMA(CrosCdmType::kPlatformCdm);
// Success case, just pass it back through the callback. // Success case, just pass it back through the callback.
std::move(callback).Run(std::move(receiver), cdm_id, std::move(decryptor), std::move(callback).Run(std::move(receiver), cdm_id, std::move(decryptor),
error_message); error_message);
...@@ -592,6 +606,7 @@ void MediaInterfaceProxy::OnChromeOsCdmCreated( ...@@ -592,6 +606,7 @@ void MediaInterfaceProxy::OnChromeOsCdmCreated(
mojo::NullRemote(), "Unable to find a CDM factory"); mojo::NullRemote(), "Unable to find a CDM factory");
return; return;
} }
ReportCdmTypeUMA(CrosCdmType::kChromeCdm);
factory->CreateCdm(key_system, cdm_config, std::move(callback)); factory->CreateCdm(key_system, cdm_config, std::move(callback));
} }
#endif // BUILDFLAG(IS_CHROMEOS_ASH) #endif // BUILDFLAG(IS_CHROMEOS_ASH)
......
...@@ -14251,6 +14251,11 @@ to ensure that the crash string is shown properly on the user-facing crash UI. ...@@ -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"/> <int value="3" label="User disabled"/>
</enum> </enum>
<enum name="CrosCdmType">
<int value="0" label="Chrome CDM"/>
<int value="1" label="Platform CDM"/>
</enum>
<enum name="CrosComponentManagerError"> <enum name="CrosComponentManagerError">
<int value="0" label="NONE"/> <int value="0" label="NONE"/>
<int value="1" label="UNKNOWN_COMPONENT"/> <int value="1" label="UNKNOWN_COMPONENT"/>
...@@ -1513,6 +1513,25 @@ reviews. Googlers can read more about this at go/gwsq-gerrit. ...@@ -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> <summary>The time it takes to create the CDM instance.</summary>
</histogram> </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" <histogram name="Media.EME.EncryptedEvent" enum="BooleanEncryptedEvent"
expires_after="2021-05-07"> expires_after="2021-05-07">
<owner>xhwang@chromium.org</owner> <owner>xhwang@chromium.org</owner>
...@@ -1674,6 +1693,16 @@ reviews. Googlers can read more about this at go/gwsq-gerrit. ...@@ -1674,6 +1693,16 @@ reviews. Googlers can read more about this at go/gwsq-gerrit.
</summary> </summary>
</histogram> </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" <histogram name="Media.EME.RequestMediaKeySystemAccess"
enum="RequestMediaKeySystemAccessStatus" expires_after="2021-06-20"> enum="RequestMediaKeySystemAccessStatus" expires_after="2021-06-20">
<owner>sandersd@chromium.org</owner> <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