Commit d469a9b6 authored by mrefaat's avatar mrefaat Committed by Commit Bot

Add logging to OpenIn feature.

Detect download failure when a corrupted PDF was downloaded and log the
OpenIn download result in all cases.

Bug: 888545
Cq-Include-Trybots: luci.chromium.try:ios-simulator-cronet;luci.chromium.try:ios-simulator-full-configs
Change-Id: I19eefd9c1b6da0c9d6b18bfcc0f3953fb33ef391
Reviewed-on: https://chromium-review.googlesource.com/c/1259295Reviewed-by: default avatarEugene But <eugenebut@chromium.org>
Reviewed-by: default avatarMark Pearson <mpearson@chromium.org>
Commit-Queue: Mohammad Refaat <mrefaat@chromium.org>
Cr-Commit-Position: refs/heads/master@{#597328}
parent 1c5da8e6
...@@ -17,6 +17,17 @@ namespace network { ...@@ -17,6 +17,17 @@ namespace network {
class SharedURLLoaderFactory; class SharedURLLoaderFactory;
} }
// Enum for the IOS.OpenIn.DownloadResult UMA histogram to log the result of
// the file download initiated when the user tap on "open in" button.
// These values are persisted to logs. Entries should not be renumbered and
// numeric values should never be reused.
enum class OpenInDownloadResult {
kSucceeded = 0,
kCanceled = 1,
kFailed = 2,
kMaxValue = kFailed,
};
@class CRWWebController; @class CRWWebController;
// Class used to handle opening files in other applications. // Class used to handle opening files in other applications.
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include "base/location.h" #include "base/location.h"
#include "base/logging.h" #include "base/logging.h"
#include "base/mac/scoped_cftyperef.h" #include "base/mac/scoped_cftyperef.h"
#include "base/metrics/histogram_macros.h"
#include "base/sequenced_task_runner.h" #include "base/sequenced_task_runner.h"
#include "base/strings/sys_string_conversions.h" #include "base/strings/sys_string_conversions.h"
#include "base/task/post_task.h" #include "base/task/post_task.h"
...@@ -62,6 +63,11 @@ const CGFloat kOverlayedViewLabelWidthPercentage = 0.7; ...@@ -62,6 +63,11 @@ const CGFloat kOverlayedViewLabelWidthPercentage = 0.7;
// Bottom margin for the label displayed on the |overlayedView_|. // Bottom margin for the label displayed on the |overlayedView_|.
const CGFloat kOverlayedViewLabelBottomMargin = 60; const CGFloat kOverlayedViewLabelBottomMargin = 60;
// Logs the result of the download process after the user taps "open in" button.
void LogOpenInDownloadResult(const OpenInDownloadResult result) {
UMA_HISTOGRAM_ENUMERATION("IOS.OpenIn.DownloadResult", result);
}
// Returns true if the file located at |url| is a valid PDF file. // Returns true if the file located at |url| is a valid PDF file.
bool HasValidPdfAtUrl(NSURL* _Nullable url) { bool HasValidPdfAtUrl(NSURL* _Nullable url) {
if (!url) if (!url)
...@@ -599,19 +605,23 @@ class OpenInControllerBridge ...@@ -599,19 +605,23 @@ class OpenInControllerBridge
if (!filePath.empty()) if (!filePath.empty())
fileURL = [NSURL fileURLWithPath:base::SysUTF8ToNSString(filePath.value())]; fileURL = [NSURL fileURLWithPath:base::SysUTF8ToNSString(filePath.value())];
if (!downloadCanceled_ && HasValidPdfAtUrl(fileURL)) { if (!downloadCanceled_ && HasValidPdfAtUrl(fileURL)) {
LogOpenInDownloadResult(OpenInDownloadResult::kSucceeded);
[self presentOpenInMenuForFileAtURL:fileURL]; [self presentOpenInMenuForFileAtURL:fileURL];
return; return;
} }
sequencedTaskRunner_->PostTask(FROM_HERE, base::BindOnce(^{ sequencedTaskRunner_->PostTask(FROM_HERE, base::BindOnce(^{
[self removeDocumentAtPath:fileURL.path]; [self removeDocumentAtPath:fileURL.path];
})); }));
OpenInDownloadResult download_result = OpenInDownloadResult::kCanceled;
if (!downloadCanceled_) { if (!downloadCanceled_) {
download_result = OpenInDownloadResult::kFailed;
if (IsIPadIdiom()) if (IsIPadIdiom())
[self hideOpenInToolbar]; [self hideOpenInToolbar];
[self removeOverlayedView]; [self removeOverlayedView];
[self showErrorWithMessage:l10n_util::GetNSStringWithFixup( [self showErrorWithMessage:l10n_util::GetNSStringWithFixup(
IDS_IOS_OPEN_IN_FILE_DOWNLOAD_FAILED)]; IDS_IOS_OPEN_IN_FILE_DOWNLOAD_FAILED)];
} }
LogOpenInDownloadResult(download_result);
} }
#pragma mark - #pragma mark -
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include "base/files/file_util.h" #include "base/files/file_util.h"
#include "base/strings/sys_string_conversions.h" #include "base/strings/sys_string_conversions.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/scoped_task_environment.h" #include "base/test/scoped_task_environment.h"
#import "ios/chrome/browser/tabs/tab.h" #import "ios/chrome/browser/tabs/tab.h"
#import "ios/chrome/browser/ui/open_in_controller.h" #import "ios/chrome/browser/ui/open_in_controller.h"
...@@ -28,6 +29,8 @@ ...@@ -28,6 +29,8 @@
namespace { namespace {
const char kOpenInDownloadResultHistogram[] = "IOS.OpenIn.DownloadResult";
class OpenInControllerTest : public PlatformTest { class OpenInControllerTest : public PlatformTest {
public: public:
OpenInControllerTest() OpenInControllerTest()
...@@ -80,9 +83,11 @@ class OpenInControllerTest : public PlatformTest { ...@@ -80,9 +83,11 @@ class OpenInControllerTest : public PlatformTest {
net::TestURLFetcherFactory factory_; net::TestURLFetcherFactory factory_;
OpenInController* open_in_controller_; OpenInController* open_in_controller_;
UIView* parent_view_; UIView* parent_view_;
base::HistogramTester histogram_tester_;
}; };
TEST_F(OpenInControllerTest, TestDisplayOpenInMenu) { TEST_F(OpenInControllerTest, TestDisplayOpenInMenu) {
histogram_tester_.ExpectTotalCount(kOpenInDownloadResultHistogram, 0);
id document_controller = id document_controller =
[OCMockObject niceMockForClass:[UIDocumentInteractionController class]]; [OCMockObject niceMockForClass:[UIDocumentInteractionController class]];
[open_in_controller_ setDocumentInteractionController:document_controller]; [open_in_controller_ setDocumentInteractionController:document_controller];
...@@ -99,11 +104,16 @@ TEST_F(OpenInControllerTest, TestDisplayOpenInMenu) { ...@@ -99,11 +104,16 @@ TEST_F(OpenInControllerTest, TestDisplayOpenInMenu) {
test_url_loader_factory_.SimulateResponseForPendingRequest( test_url_loader_factory_.SimulateResponseForPendingRequest(
pending_request->request.url.spec(), pdf_str); pending_request->request.url.spec(), pdf_str);
scoped_task_environment_.RunUntilIdle(); scoped_task_environment_.RunUntilIdle();
histogram_tester_.ExpectBucketCount(kOpenInDownloadResultHistogram,
static_cast<base::HistogramBase::Sample>(
OpenInDownloadResult::kSucceeded),
1);
histogram_tester_.ExpectTotalCount(kOpenInDownloadResultHistogram, 1);
EXPECT_OCMOCK_VERIFY(document_controller); EXPECT_OCMOCK_VERIFY(document_controller);
} }
TEST_F(OpenInControllerTest, TestCorruptedPDFDownload) { TEST_F(OpenInControllerTest, TestCorruptedPDFDownload) {
histogram_tester_.ExpectTotalCount(kOpenInDownloadResultHistogram, 0);
id document_controller = id document_controller =
[OCMockObject niceMockForClass:[UIDocumentInteractionController class]]; [OCMockObject niceMockForClass:[UIDocumentInteractionController class]];
[open_in_controller_ setDocumentInteractionController:document_controller]; [open_in_controller_ setDocumentInteractionController:document_controller];
...@@ -119,7 +129,11 @@ TEST_F(OpenInControllerTest, TestCorruptedPDFDownload) { ...@@ -119,7 +129,11 @@ TEST_F(OpenInControllerTest, TestCorruptedPDFDownload) {
test_url_loader_factory_.SimulateResponseForPendingRequest( test_url_loader_factory_.SimulateResponseForPendingRequest(
pending_request->request.url.spec(), pdf_str.substr(pdf_str.size() / 2)); pending_request->request.url.spec(), pdf_str.substr(pdf_str.size() / 2));
scoped_task_environment_.RunUntilIdle(); scoped_task_environment_.RunUntilIdle();
histogram_tester_.ExpectBucketCount(
kOpenInDownloadResultHistogram,
static_cast<base::HistogramBase::Sample>(OpenInDownloadResult::kFailed),
1);
histogram_tester_.ExpectTotalCount(kOpenInDownloadResultHistogram, 1);
EXPECT_OCMOCK_VERIFY(document_controller); EXPECT_OCMOCK_VERIFY(document_controller);
} }
......
...@@ -26495,6 +26495,16 @@ Called by update_gpu_driver_bug_workaround_entries.py.--> ...@@ -26495,6 +26495,16 @@ Called by update_gpu_driver_bug_workaround_entries.py.-->
<int value="2" label="Remote suggestions collapsed"/> <int value="2" label="Remote suggestions collapsed"/>
</enum> </enum>
<enum name="IOSOpenInDownloadResult">
<int value="0" label="Download Succeeded"/>
<int value="1" label="Download Canceled">
User canceled the download manually.
</int>
<int value="2" label="Download Failed">
Download failed either by getting a corrupted file or no file at all.
</int>
</enum>
<enum name="IOSPageLoadCountNavigationType"> <enum name="IOSPageLoadCountNavigationType">
<int value="0" label="Chrome URL Navigation"/> <int value="0" label="Chrome URL Navigation"/>
<int value="1" label="Same Document Web Navigation"/> <int value="1" label="Same Document Web Navigation"/>
...@@ -39347,6 +39347,14 @@ uploading your change for review. ...@@ -39347,6 +39347,14 @@ uploading your change for review.
</summary> </summary>
</histogram> </histogram>
<histogram name="IOS.OpenIn.DownloadResult" enum="IOSOpenInDownloadResult">
<owner>mrefaat@chromium.org</owner>
<summary>
The result of the download operation done when the user taps &quot;open
in&quot; button to open a file by a different application.
</summary>
</histogram>
<histogram name="IOS.PageLoadCount.Counts" <histogram name="IOS.PageLoadCount.Counts"
enum="IOSPageLoadCountNavigationType"> enum="IOSPageLoadCountNavigationType">
<owner>danyao@chromium.org</owner> <owner>danyao@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