blob: 85fbdaf1ea348ca477e33f6d3fe4726441cb4277 [file] [log] [blame]
// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef SRC_DEVELOPER_FEEDBACK_UTILS_COBALT_H_
#define SRC_DEVELOPER_FEEDBACK_UTILS_COBALT_H_
#include <fuchsia/cobalt/cpp/fidl.h>
#include <lib/fit/function.h>
#include <lib/sys/cpp/service_directory.h>
#include <lib/zx/time.h>
#include <map>
#include <memory>
#include <set>
#include <utility>
#include "src/developer/feedback/utils/cobalt_event.h"
#include "src/lib/backoff/exponential_backoff.h"
#include "src/lib/fxl/functional/cancelable_callback.h"
namespace feedback {
// Log events to cobalt.
class Cobalt {
public:
// We expect fuchsia.cobalt.LoggerFactory to be in |services|.
Cobalt(async_dispatcher_t* dispatcher, std::shared_ptr<sys::ServiceDirectory> services);
// Log an occurrence event with fuchsia.cobalt.Logger with the provided parameters. If the service
// is not accessible, keep the parameters to try again later.
template <typename EventCodeType>
void LogOccurrence(
EventCodeType event_code,
fit::callback<void(fuchsia::cobalt::Status)> callback = [](fuchsia::cobalt::Status) {}) {
LogEvent(CobaltEvent(event_code), std::move(callback));
}
// Log a count event with fuchsia.cobalt.Logger with the provided parameters. If the service is
// not accessible, keep the parameters to try again later.
template <typename EventCodeType>
void LogCount(
EventCodeType event_code, uint64_t count,
fit::callback<void(fuchsia::cobalt::Status)> callback = [](fuchsia::cobalt::Status) {}) {
LogEvent(CobaltEvent(event_code, count), std::move(callback));
}
private:
struct PendingEvent {
PendingEvent(CobaltEvent event, fit::callback<void(fuchsia::cobalt::Status)> callback)
: event(event), callback(std::move(callback)) {}
CobaltEvent event;
fit::callback<void(fuchsia::cobalt::Status)> callback;
};
void ConnectToLogger(fidl::InterfaceRequest<fuchsia::cobalt::Logger> logger_request);
void RetryConnectingToLogger();
void LogEvent(CobaltEvent event, fit::callback<void(fuchsia::cobalt::Status)> callback);
void SendEvent(uint64_t event_id);
void SendAllPendingEvents();
async_dispatcher_t* dispatcher_;
std::shared_ptr<sys::ServiceDirectory> services_;
fuchsia::cobalt::LoggerFactoryPtr logger_factory_;
fuchsia::cobalt::LoggerPtr logger_;
// An event is pending if it has been written into a channel, but has not been acknowledged by
// the recipient.
std::map<uint64_t, PendingEvent> pending_events_;
backoff::ExponentialBackoff logger_reconnection_backoff_;
// We need to be able to cancel a posted reconnection task when |Cobalt| is destroyed.
fxl::CancelableClosure reconnect_task_;
uint64_t next_event_id_ = 0;
};
} // namespace feedback
#endif // SRC_DEVELOPER_FEEDBACK_UTILS_COBALT_H_