File: android_telemetry_service.h

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (160 lines) | stat: -rw-r--r-- 6,344 bytes parent folder | download | duplicates (6)
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_