0

[lensoverlay] Record metric for page count

Adds a metric for the PDF page count retrieved from the renderer.

Bug: 366028802
Change-Id: I90dfaccac0ce507784bd3e8ce61f70119abd65f4
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6032193
Reviewed-by: Tom Sepez <tsepez@chromium.org>
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: Duncan Mercer <mercerd@google.com>
Reviewed-by: Justin Donnelly <jdonnelly@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1385207}
This commit is contained in:
Duncan Mercer
2024-11-19 21:12:16 +00:00
committed by Chromium LUCI CQ
parent bc60948a72
commit 10432e5451
9 changed files with 86 additions and 31 deletions

@ -55,6 +55,7 @@
#include "components/find_in_page/find_tab_helper.h"
#include "components/lens/lens_features.h"
#include "components/lens/lens_overlay_metrics.h"
#include "components/lens/lens_overlay_page_content_mime_type.h"
#include "components/lens/lens_overlay_permission_utils.h"
#include "components/permissions/permission_request_manager.h"
#include "components/sessions/content/session_tab_helper.h"
@ -1487,12 +1488,13 @@ void LensOverlayController::ContinueCreateInitializationData(
void LensOverlayController::StorePageContentAndContinueInitialization(
std::unique_ptr<OverlayInitializationData> initialization_data,
std::vector<uint8_t> bytes,
lens::PageContentMimeType content_type) {
lens::PageContentMimeType content_type,
std::optional<uint32_t> page_count) {
initialization_data->page_content_bytes_ = bytes;
initialization_data->page_content_type_ = content_type;
InitializeOverlay(std::move(initialization_data));
RecordDocumentSizes();
RecordDocumentMetrics(page_count);
}
void LensOverlayController::GetPageContextualization(
@ -1500,7 +1502,7 @@ void LensOverlayController::GetPageContextualization(
// If the contextual searchbox is disabled, exit early.
if (!lens::features::IsLensOverlayContextualSearchboxEnabled()) {
std::move(callback).Run(std::vector<uint8_t>(),
lens::PageContentMimeType::kNone);
lens::PageContentMimeType::kNone, std::nullopt);
return;
}
@ -1540,21 +1542,22 @@ void LensOverlayController::GetPageContextualization(
}
std::move(callback).Run(std::vector<uint8_t>(),
lens::PageContentMimeType::kNone);
lens::PageContentMimeType::kNone, std::nullopt);
}
#if BUILDFLAG(ENABLE_PDF)
void LensOverlayController::OnPdfBytesReceived(
PageContentRetrievedCallback callback,
pdf::mojom::PdfListener::GetPdfBytesStatus status,
const std::vector<uint8_t>& bytes) {
const std::vector<uint8_t>& bytes,
uint32_t page_count) {
// TODO(b/370530197): Show user error message if status is not success.
if (status != pdf::mojom::PdfListener::GetPdfBytesStatus::kSuccess) {
std::move(callback).Run(std::vector<uint8_t>(),
lens::PageContentMimeType::kPdf);
lens::PageContentMimeType::kPdf, page_count);
return;
}
std::move(callback).Run(bytes, lens::PageContentMimeType::kPdf);
std::move(callback).Run(bytes, lens::PageContentMimeType::kPdf, page_count);
}
#endif // BUILDFLAG(ENABLE_PDF)
@ -1564,12 +1567,13 @@ void LensOverlayController::OnInnerTextReceived(
if (!result || result->inner_text.size() >
lens::features::GetLensOverlayFileUploadLimitBytes()) {
std::move(callback).Run(std::vector<uint8_t>(),
lens::PageContentMimeType::kPlainText);
lens::PageContentMimeType::kPlainText,
std::nullopt);
return;
}
std::move(callback).Run(std::vector<uint8_t>(result->inner_text.begin(),
result->inner_text.end()),
lens::PageContentMimeType::kPlainText);
lens::PageContentMimeType::kPlainText, std::nullopt);
}
void LensOverlayController::OnInnerHtmlReceived(
@ -1578,11 +1582,11 @@ void LensOverlayController::OnInnerHtmlReceived(
if (!result.has_value() ||
result->size() > lens::features::GetLensOverlayFileUploadLimitBytes()) {
std::move(callback).Run(std::vector<uint8_t>(),
lens::PageContentMimeType::kHtml);
lens::PageContentMimeType::kHtml, std::nullopt);
return;
}
std::move(callback).Run(std::vector<uint8_t>(result->begin(), result->end()),
lens::PageContentMimeType::kHtml);
lens::PageContentMimeType::kHtml, std::nullopt);
}
void LensOverlayController::AddBoundingBoxesToInitializationData(
@ -1636,7 +1640,8 @@ void LensOverlayController::TryUpdatePageContextualization() {
void LensOverlayController::UpdatePageContextualization(
std::vector<uint8_t> bytes,
lens::PageContentMimeType content_type) {
lens::PageContentMimeType content_type,
std::optional<uint32_t> page_count) {
if (!lens::features::IsLensOverlayContextualSearchboxEnabled()) {
return;
}
@ -1664,7 +1669,7 @@ void LensOverlayController::UpdatePageContextualization(
initialization_data_->page_content_bytes_,
initialization_data_->page_content_type_, GetPageURL());
RecordDocumentSizes();
RecordDocumentMetrics(page_count);
}
void LensOverlayController::UpdateGhostLoaderState(bool suppress_ghost_loader,
@ -2714,11 +2719,18 @@ void LensOverlayController::RecordEndOfSessionMetrics(
session_duration);
}
void LensOverlayController::RecordDocumentSizes() {
void LensOverlayController::RecordDocumentMetrics(
std::optional<uint32_t> page_count) {
auto content_type = initialization_data_->page_content_type_;
lens::RecordDocumentSizeBytes(
content_type, initialization_data_->page_content_bytes_.size());
if (page_count.has_value() &&
content_type == lens::PageContentMimeType::kPdf) {
lens::RecordPdfPageCount(page_count.value());
return;
}
// Fetch and record the other content type for representing the webpage.
auto* render_frame_host = tab_->GetContents()->GetPrimaryMainFrame();
if (content_type == lens::PageContentMimeType::kHtml) {

@ -96,10 +96,15 @@ class Profile;
extern void* kLensOverlayPreselectionWidgetIdentifier;
// Callback type alias for page content bytes retrieved.
// Callback type alias for page content bytes retrieved. `content_type` is the
// mime type of the bytes. `pdf_page_count` is the number of pages in the
// document being retrieved, not necessarily the number of pages in `bytes`. For
// example, if the document is a PDF, `pdf_page_count` is the number of pages in
// the PDF, while `bytes` could be empty because the PDF is too large.
using PageContentRetrievedCallback =
base::OnceCallback<void(std::vector<uint8_t> bytes,
lens::PageContentMimeType content_type)>;
lens::PageContentMimeType content_type,
std::optional<uint32_t> pdf_page_count)>;
// Manages all state associated with the lens overlay.
// This class is not thread safe. It should only be used from the browser
@ -655,11 +660,13 @@ class LensOverlayController : public LensSearchboxClient,
const std::vector<gfx::Rect>& all_bounds,
SkBitmap rgb_screenshot);
// Stores the page content and continues the initialization process.
// Stores the page content and continues the initialization process. Also
// records the page count for PDF.
void StorePageContentAndContinueInitialization(
std::unique_ptr<OverlayInitializationData> initialization_data,
std::vector<uint8_t> bytes,
lens::PageContentMimeType content_type);
lens::PageContentMimeType content_type,
std::optional<uint32_t> pdf_page_count);
// Tries to fetch the underlying page content bytes to use for
// contextualization. If page content can not be retrieved, the callback will
@ -671,7 +678,8 @@ class LensOverlayController : public LensSearchboxClient,
// them in initialization data.
void OnPdfBytesReceived(PageContentRetrievedCallback callback,
pdf::mojom::PdfListener::GetPdfBytesStatus status,
const std::vector<uint8_t>& bytes);
const std::vector<uint8_t>& bytes,
uint32_t pdf_page_count);
#endif // BUILDFLAG(ENABLE_PDF)
// Callback for when the inner text is retrieved from the underlying page.
@ -695,7 +703,8 @@ class LensOverlayController : public LensSearchboxClient,
// Updates the query flow with the new page content bytes. A request will only
// be sent if the bytes are different from the previous bytes sent.
void UpdatePageContextualization(std::vector<uint8_t> bytes,
lens::PageContentMimeType content_type);
lens::PageContentMimeType content_type,
std::optional<uint32_t> pdf_page_count);
// Updates state of the ghost loader. |suppress_ghost_loader| is true when
// the page bytes can't be uploaded. |reset_loading_state| is true whenever
@ -933,10 +942,11 @@ class LensOverlayController : public LensSearchboxClient,
void RecordEndOfSessionMetrics(
lens::LensOverlayDismissalSource dismissal_source);
// Records the UMA for the size of the document where the contextual search
// box was shown. If this is a webpage, records the size of the innerHtml and
// the innerText. If this is a PDF, records the byte size of the PDF.
void RecordDocumentSizes();
// Records the UMA for the metrics relating to the document where the
// contextual search box was shown. If this is a webpage, records the size of
// the innerHtml and the innerText. If this is a PDF, records the byte size of
// the PDF and the number of pages. `pdf_page_count` is only used for PDFs.
void RecordDocumentMetrics(std::optional<uint32_t> pdf_page_count);
// Callback to record the size of the innerText once it is fetched.
void RecordInnerTextSize(

@ -4235,6 +4235,10 @@ IN_PROC_BROWSER_TEST_P(LensOverlayControllerBrowserPDFContextualizationTest,
histogram_tester.ExpectTotalCount(
"Lens.Overlay.ByContentType.Pdf.DocumentSize",
/*expected_count=*/2);
// Verify the histogram two documents of one page.
histogram_tester.ExpectBucketCount(
"Lens.Overlay.ByDocumentType.Pdf.PageCount", /*sample*/ 1,
/*expected_count=*/2);
}
IN_PROC_BROWSER_TEST_P(LensOverlayControllerBrowserPDFContextualizationTest,
@ -4314,6 +4318,9 @@ IN_PROC_BROWSER_TEST_P(LensOverlayControllerBrowserPDFContextualizationTest,
histogram_tester.ExpectTotalCount(
"Lens.Overlay.ByContentType.Pdf.DocumentSize",
/*expected_count=*/1);
histogram_tester.ExpectUniqueSample(
"Lens.Overlay.ByDocumentType.Pdf.PageCount", /*sample*/ 1,
/*expected_bucket_count=*/1);
}
// TODO(crbug.com/378810677): Flaky on all platforms.
@ -4735,6 +4742,8 @@ IN_PROC_BROWSER_TEST_F(LensOverlayControllerBrowserTest,
histogram_tester.ExpectTotalCount(
"Lens.Overlay.ByContentType.Html.DocumentSize",
/*expected_count=*/2);
histogram_tester.ExpectTotalCount("Lens.Overlay.ByDocumentType.Pdf.PageCount",
/*expected_count=*/0);
}
IN_PROC_BROWSER_TEST_F(LensOverlayControllerBrowserTest,

@ -304,4 +304,9 @@ void RecordDocumentSizeBytes(lens::PageContentMimeType page_content_type,
document_size_bytes / 1000);
}
void RecordPdfPageCount(uint32_t page_count) {
base::UmaHistogramCounts1000("Lens.Overlay.ByDocumentType.Pdf.PageCount",
page_count);
}
} // namespace lens

@ -104,6 +104,10 @@ void MaybeRecordContextualSearchBoxShown(
// sliced by content type.
void RecordDocumentSizeBytes(lens::PageContentMimeType page_content_type,
size_t document_size_bytes);
// Record the number of pages in a PDF.
void RecordPdfPageCount(uint32_t page_count);
} // namespace lens
#endif // COMPONENTS_LENS_LENS_OVERLAY_METRICS_H_

@ -212,8 +212,8 @@ void PDFDocumentHelper::GetPdfBytes(
uint32_t size_limit,
pdf::mojom::PdfListener::GetPdfBytesCallback callback) {
if (!remote_pdf_client_) {
std::move(callback).Run(
pdf::mojom::PdfListener::GetPdfBytesStatus::kFailed, {});
std::move(callback).Run(pdf::mojom::PdfListener::GetPdfBytesStatus::kFailed,
/*bytes=*/{}, /*page_count=*/0);
return;
}
remote_pdf_client_->GetPdfBytes(size_limit, std::move(callback));

@ -28,9 +28,11 @@ interface PdfListener {
// Get PDF bytes. If the size of the PDF in bytes is larger than `size_limit`,
// an empty vector will be returned instead. `bytes` is only guaranteed to be
// from the PDF engine if `status` is `kSuccess`.
// from the PDF engine if `status` is `kSuccess`. `page_count` is the number
// of pages in the PDF displayed in the renderer, not the number of pages
// returned in `bytes`.
GetPdfBytes(uint32 size_limit)
=> (GetPdfBytesStatus status, array<uint8> bytes);
=> (GetPdfBytesStatus status, array<uint8> bytes, uint32 page_count);
};
// Browser-side interface used by PDF renderers.

@ -1528,12 +1528,15 @@ void PdfViewWebPlugin::SetSelectionBounds(const gfx::PointF& base,
void PdfViewWebPlugin::GetPdfBytes(uint32_t size_limit,
GetPdfBytesCallback callback) {
uint32_t page_count = engine_->GetNumberOfPages();
if (engine_->GetLoadedByteSize() > size_limit) {
std::move(callback).Run(GetPdfBytesStatus::kSizeLimitExceeded, {});
std::move(callback).Run(GetPdfBytesStatus::kSizeLimitExceeded, {},
page_count);
return;
}
std::move(callback).Run(GetPdfBytesStatus::kSuccess, engine_->GetSaveData());
std::move(callback).Run(GetPdfBytesStatus::kSuccess, engine_->GetSaveData(),
page_count);
}
bool PdfViewWebPlugin::IsValid() const {

@ -23,7 +23,7 @@ chromium-metrics-reviews@google.com.
<histograms>
<!-- Represents the MIME types that are retrieved from the page content.
Corresponds to the content type set in the request to the server. -->
Corresponds to the content type set in the request to the server. -->
<variants name="ContentTypes">
<variant name="Html"/>
@ -124,6 +124,16 @@ chromium-metrics-reviews@google.com.
<token key="ContentType" variants="ContentTypes"/>
</histogram>
<histogram name="Lens.Overlay.ByDocumentType.Pdf.PageCount" units="Pages"
expires_after="2025-05-06">
<owner>mercerd@google.com</owner>
<owner>lens-chrome@google.com</owner>
<summary>
Recorded whenever a PDF is fetched from the PDF renderer. Records the number
of pages in the PDF that was fetched.
</summary>
</histogram>
<histogram name="Lens.Overlay.ByDocumentType.{DocumentType}.Invoked"
enum="Boolean" expires_after="2025-05-06">
<owner>stanfield@google.com</owner>