blob: ce59db861347493570da12a7cdd97af40e1a31de [file] [log] [blame]
Kevin Marshall05e29bd2020-03-19 21:55:441// Copyright 2020 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef FUCHSIA_BASE_LEGACYMETRICS_CLIENT_H_
6#define FUCHSIA_BASE_LEGACYMETRICS_CLIENT_H_
7
8#include <fuchsia/legacymetrics/cpp/fidl.h>
9
10#include <memory>
11#include <vector>
12
13#include "base/callback.h"
14#include "base/memory/weak_ptr.h"
15#include "base/sequence_checker.h"
Akira Baruah7b75418b2020-12-11 01:35:0916#include "base/time/time.h"
Kevin Marshall05e29bd2020-03-19 21:55:4417#include "base/timer/timer.h"
18#include "fuchsia/base/legacymetrics_user_event_recorder.h"
19
20namespace cr_fuchsia {
21
22// Used to report events & histogram data to the
23// fuchsia.legacymetrics.MetricsRecorder service.
24// LegacyMetricsClient must be Start()ed on an IO-capable sequence.
25// Cannot be used in conjunction with other metrics reporting services.
26// Must be constructed, used, and destroyed on the same sequence.
27class LegacyMetricsClient {
28 public:
Kevin Marshallebe60c42020-04-14 22:01:2429 // Maximum number of Events to send to Record() at a time, so as to not exceed
30 // the 64KB FIDL maximum message size.
31 static constexpr size_t kMaxBatchSize = 50;
32
Akira Baruah7b75418b2020-12-11 01:35:0933 // Constants for FIDL reconnection with exponential backoff.
34 static constexpr base::TimeDelta kInitialReconnectDelay =
35 base::TimeDelta::FromSeconds(1);
36 static constexpr base::TimeDelta kMaxReconnectDelay =
37 base::TimeDelta::FromHours(1);
38 static constexpr size_t kReconnectBackoffFactor = 2;
39
Kevin Marshall05e29bd2020-03-19 21:55:4440 using ReportAdditionalMetricsCallback = base::RepeatingCallback<void(
Kevin Marshallebe60c42020-04-14 22:01:2441 base::OnceCallback<void(std::vector<fuchsia::legacymetrics::Event>)>)>;
Kevin Marshallaa7f5162020-06-04 23:32:3142 using NotifyFlushCallback =
43 base::OnceCallback<void(base::OnceClosure completion_cb)>;
Kevin Marshall05e29bd2020-03-19 21:55:4444
45 LegacyMetricsClient();
Kevin Marshall05e29bd2020-03-19 21:55:4446 ~LegacyMetricsClient();
47
48 explicit LegacyMetricsClient(const LegacyMetricsClient&) = delete;
49 LegacyMetricsClient& operator=(const LegacyMetricsClient&) = delete;
50
51 // Starts buffering data and schedules metric reporting after every
52 // |report_interval|.
53 void Start(base::TimeDelta report_interval);
54
Kevin Marshallebe60c42020-04-14 22:01:2455 // Sets an asynchronous |callback| to be invoked just prior to reporting,
56 // allowing users to asynchronously gather and provide additional custom
57 // metrics. |callback| will receive the list of metrics when they are ready.
58 // Reporting is paused until |callback| is fulfilled.
59 // If used, then this method must be called before calling Start().
Kevin Marshall05e29bd2020-03-19 21:55:4460 void SetReportAdditionalMetricsCallback(
61 ReportAdditionalMetricsCallback callback);
62
Kevin Marshallaa7f5162020-06-04 23:32:3163 // Sets a |callback| which is invoked to warn that the connection to the
64 // remote MetricsRecorder will be terminated. The completion closure passed to
65 // |callback| should be invoked to signal flush completion.
66 void SetNotifyFlushCallback(NotifyFlushCallback callback);
67
Hai Bid0224f92020-10-19 23:47:4868 // Use when caller needs an explicit flush and then disconnect, such as before
69 // termination. Caller will be notified when all events in the buffer are
70 // sent.
71 void FlushAndDisconnect(base::OnceClosure on_flush_complete);
72
Kevin Marshall05e29bd2020-03-19 21:55:4473 private:
Akira Baruah7b75418b2020-12-11 01:35:0974 void ConnectAndStartReporting();
Kevin Marshall05e29bd2020-03-19 21:55:4475 void ScheduleNextReport();
Kevin Marshallebe60c42020-04-14 22:01:2476 void StartReport();
77 void Report(std::vector<fuchsia::legacymetrics::Event> additional_metrics);
Kevin Marshall05e29bd2020-03-19 21:55:4478 void OnMetricsRecorderDisconnected(zx_status_t status);
Kevin Marshallaa7f5162020-06-04 23:32:3179 void OnCloseSoon();
Kevin Marshall05e29bd2020-03-19 21:55:4480
Kevin Marshallaa7f5162020-06-04 23:32:3181 // Incrementally sends the contents of |to_send_| to |metrics_recorder_|.
82 void DrainBuffer();
Kevin Marshallebe60c42020-04-14 22:01:2483
Akira Baruah7b75418b2020-12-11 01:35:0984 base::TimeDelta reconnect_delay_ = kInitialReconnectDelay;
Kevin Marshall05e29bd2020-03-19 21:55:4485 base::TimeDelta report_interval_;
86 ReportAdditionalMetricsCallback report_additional_callback_;
Kevin Marshallaa7f5162020-06-04 23:32:3187 NotifyFlushCallback notify_flush_callback_;
88 bool is_flushing_ = false;
89 bool record_ack_pending_ = false;
90 std::vector<fuchsia::legacymetrics::Event> to_send_;
Kevin Marshall05e29bd2020-03-19 21:55:4491 std::unique_ptr<LegacyMetricsUserActionRecorder> user_events_recorder_;
92
93 fuchsia::legacymetrics::MetricsRecorderPtr metrics_recorder_;
Akira Baruah7b75418b2020-12-11 01:35:0994 base::RetainingOneShotTimer reconnect_timer_;
95 base::RetainingOneShotTimer report_timer_;
Kevin Marshall05e29bd2020-03-19 21:55:4496 SEQUENCE_CHECKER(sequence_checker_);
Kevin Marshallebe60c42020-04-14 22:01:2497
Hai Bid0224f92020-10-19 23:47:4898 base::OnceClosure on_flush_complete_;
99
Kevin Marshallebe60c42020-04-14 22:01:24100 // Prevents use-after-free if |report_additional_callback_| is invoked after
101 // |this| is destroyed.
102 base::WeakPtrFactory<LegacyMetricsClient> weak_factory_{this};
Kevin Marshall05e29bd2020-03-19 21:55:44103};
104
105} // namespace cr_fuchsia
106
107#endif // FUCHSIA_BASE_LEGACYMETRICS_CLIENT_H_