1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160
|
// Copyright 2018 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_SAFE_BROWSING_TELEMETRY_ANDROID_ANDROID_TELEMETRY_SERVICE_H_
#define CHROME_BROWSER_SAFE_BROWSING_TELEMETRY_ANDROID_ANDROID_TELEMETRY_SERVICE_H_
#include <memory>
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "chrome/browser/safe_browsing/telemetry/telemetry_service.h"
#include "components/download/public/common/download_item.h"
#include "components/download/public/common/simple_download_manager_coordinator.h"
#include "components/safe_browsing/android/safe_browsing_api_handler_util.h"
#include "components/safe_browsing/content/browser/safe_browsing_navigation_observer_manager.h"
#include "components/safe_browsing/core/common/proto/csd.pb.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/download_manager.h"
class Profile;
class PrefService;
namespace safe_browsing {
// Enumerates the possibilities for whether the CSBRR report was sent (or not).
enum class ApkDownloadTelemetryOutcome {
NOT_SENT_SAFE_BROWSING_NOT_ENABLED = 0,
// |web_contents| was nullptr. This happens sometimes when downloads are
// resumed but it's not clear exactly when.
NOT_SENT_MISSING_WEB_CONTENTS = 1,
// No ping sent because the user is in Incognito mode.
NOT_SENT_INCOGNITO = 2,
// No ping sent because the user hasn't enabled extended reporting.
// Deprecated for NOT_SENT_UNCONSENTED.
NOT_SENT_EXTENDED_REPORTING_DISABLED = 3,
// Download was cancelled.
NOT_SENT_DOWNLOAD_CANCELLED = 4,
// Failed to serialize the report.
NOT_SENT_FAILED_TO_SERIALIZE = 5,
// Feature not enabled so don't send.
NOT_SENT_FEATURE_NOT_ENABLED = 6,
// Download completed. Ping sent.
SENT = 7,
// No ping sent because the user hasn't enabled enhanced protection and
// extended reporting.
NOT_SENT_UNCONSENTED = 8,
kMaxValue = NOT_SENT_UNCONSENTED
};
// This class is used to send telemetry information to Safe Browsing for
// security related incidents. The information is sent only if:
// 1. The user has opted in to extended reporting, AND
// 2. The security incident did not happen in an incognito window.
// As the name suggests, this works only on Android.
// The following events are currently considered security related incidents from
// the perspective of this class:
// 1. Downloading off-market APKs. See: go/zurkon-v1-referrer-dd
class AndroidTelemetryService
: public download::DownloadItem::Observer,
public download::SimpleDownloadManagerCoordinator::Observer,
public TelemetryService {
public:
explicit AndroidTelemetryService(Profile* profile);
AndroidTelemetryService(const AndroidTelemetryService&) = delete;
AndroidTelemetryService& operator=(const AndroidTelemetryService&) = delete;
~AndroidTelemetryService() override;
// download::SimpleDownloadManagerCoordinator::Observer.
void OnDownloadCreated(download::DownloadItem* item) override;
// download::DownloadItem::Observer.
void OnDownloadUpdated(download::DownloadItem* item) override;
void OnDownloadRemoved(download::DownloadItem* item) override;
Profile* profile() { return profile_; }
private:
friend class AndroidTelemetryServiceTest;
using OnGetReportDoneCallback = base::OnceCallback<void(
std::unique_ptr<ClientSafeBrowsingReportRequest>)>;
enum class ApkDownloadTelemetryIncompleteReason {
// |web_contents| was nullptr. This happens sometimes when downloads are
// resumed but it's not clear exactly when.
MISSING_WEB_CONTENTS = 0,
// Navigation manager wasn't ready yet to provide the referrer chain.
SB_NAVIGATION_MANAGER_NOT_READY = 1,
// Full referrer chain captured.
COMPLETE = 2,
// No render frame host existed for the download
MISSING_RENDER_FRAME_HOST = 3,
// The render frame host had not committed to a valid URL
RENDER_FRAME_HOST_INVALID_URL = 4,
kMaxValue = RENDER_FRAME_HOST_INVALID_URL,
};
struct ReferrerChainResult {
ApkDownloadTelemetryIncompleteReason missing_reason;
SafeBrowsingNavigationObserverManager::AttributionResult result;
bool triggered_by_intent = false;
};
// Whether the ping can be sent, based on empty web_contents, or incognito
// mode, or extended reporting opt-in status,
bool CanSendPing(download::DownloadItem* item);
// Populates the `ReferrerChainData` on `item` so that we can use it during
// report construction.
void FillReferrerChain(download::DownloadItem* item);
// Sets the relevant fields in an instance of
// |ClientSafeBrowsingReportRequest| proto and returns that proto
// asynchronously.
void GetReport(download::DownloadItem* item,
OnGetReportDoneCallback callback);
// Callback when we know if app verification is enabled.
void IsVerifyAppsEnabled(
std::unique_ptr<ClientSafeBrowsingReportRequest> report,
OnGetReportDoneCallback callback,
VerifyAppsEnabledResult result);
// Callback when report generation is complete.
void OnGetReportDone(download::DownloadItem* item,
std::unique_ptr<ClientSafeBrowsingReportRequest> report);
// Sends |report| proto to the Safe Browsing backend. The report may not be
// sent if the proto fails to serialize.
void MaybeSendApkDownloadReport(
content::BrowserContext* browser_context,
std::unique_ptr<ClientSafeBrowsingReportRequest> report);
// Helper method to get prefs from |profile_|.
const PrefService* GetPrefs();
// Profile associated with this instance. Unowned.
raw_ptr<Profile> profile_;
// Referrer chains are best computed at download start, before we
// know whether it will be suitable to send a ping. In order to log
// metrics only for downloads that send a ping, we persist the
// outcome of referrer chain computation.
std::map<download::DownloadItem*, ReferrerChainResult> referrer_chain_result_;
// The collection of `DownloadItem`s we're currently collecting reports for.
std::set<download::DownloadItem*> reports_in_progress_;
base::WeakPtrFactory<AndroidTelemetryService> weak_ptr_factory_{this};
};
} // namespace safe_browsing
#endif // CHROME_BROWSER_SAFE_BROWSING_TELEMETRY_ANDROID_ANDROID_TELEMETRY_SERVICE_H_
|