1 // Copyright 2016 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 REMOTING_BASE_TELEMETRY_LOG_WRITER_H_
6 #define REMOTING_BASE_TELEMETRY_LOG_WRITER_H_
7 
8 #include <string>
9 
10 #include "base/callback.h"
11 #include "base/containers/circular_deque.h"
12 #include "base/macros.h"
13 #include "base/memory/scoped_refptr.h"
14 #include "base/threading/thread_checker.h"
15 #include "base/timer/timer.h"
16 #include "base/values.h"
17 #include "net/base/backoff_entry.h"
18 #include "remoting/base/chromoting_event.h"
19 #include "remoting/base/chromoting_event_log_writer.h"
20 #include "remoting/base/oauth_token_getter.h"
21 #include "remoting/base/url_request.h"
22 
23 namespace network {
24 class SharedURLLoaderFactory;
25 }  // namespace network
26 
27 namespace remoting {
28 
29 namespace apis {
30 namespace v1 {
31 
32 class CreateEventRequest;
33 class CreateEventResponse;
34 
35 }  // namespace v1
36 }  // namespace apis
37 
38 class ProtobufHttpClient;
39 class ProtobufHttpStatus;
40 
41 // TelemetryLogWriter sends log entries (ChromotingEvent) to the telemetry
42 // server.
43 // Logs to be sent will be queued and sent when it is available. Logs failed
44 // to send will be retried for a few times and dropped if they still can't be
45 // sent.
46 // The log writer should be used entirely on one thread after it is created,
47 // unless otherwise noted.
48 class TelemetryLogWriter : public ChromotingEventLogWriter {
49  public:
50   explicit TelemetryLogWriter(std::unique_ptr<OAuthTokenGetter> token_getter);
51 
52   ~TelemetryLogWriter() override;
53 
54   void Init(scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory);
55 
56   // Push the log entry to the pending list and send out all the pending logs.
57   void Log(const ChromotingEvent& entry) override;
58 
59  private:
60   void SendPendingEntries();
61   void DoSend(const apis::v1::CreateEventRequest& request);
62   void OnSendLogResult(const ProtobufHttpStatus& status,
63                        std::unique_ptr<apis::v1::CreateEventResponse> response);
64 
65   // Returns true if there are no events sending or pending.
66   bool IsIdleForTesting();
67 
68   THREAD_CHECKER(thread_checker_);
69 
70   std::unique_ptr<OAuthTokenGetter> token_getter_;
71   std::unique_ptr<ProtobufHttpClient> http_client_;
72   net::BackoffEntry backoff_;
73   base::OneShotTimer backoff_timer_;
74 
75   // Entries to be sent.
76   base::circular_deque<ChromotingEvent> pending_entries_;
77 
78   // Entries being sent.
79   // These will be pushed back to pending_entries if error occurs.
80   base::circular_deque<ChromotingEvent> sending_entries_;
81 
82   friend class TelemetryLogWriterTest;
83   DISALLOW_COPY_AND_ASSIGN(TelemetryLogWriter);
84 };
85 
86 }  // namespace remoting
87 #endif  // REMOTING_BASE_TELEMETRY_LOG_WRITER_H_
88