chromium/components/ukm/singular_ukm_entry.h

// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef COMPONENTS_UKM_SINGULAR_UKM_ENTRY_H_
#define COMPONENTS_UKM_SINGULAR_UKM_ENTRY_H_

#include <memory>

#include "base/logging.h"
#include "base/memory/raw_ptr.h"
#include "base/sequence_checker.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "services/metrics/public/cpp/ukm_source_id.h"
#include "services/metrics/public/mojom/ukm_interface.mojom.h"

namespace ukm {

template <typename>
class SingularUkmEntry;

// Creates the SingularUkmInterface receiver.
void CreateSingularUkmInterface(
    mojo::PendingReceiver<mojom::SingularUkmInterface> receiver);

// Singular UKM Entries are UKM Entries that can be 'recorded' multiple times
// but only the last one will be recorded by the UKM Service. While not
// currently supported, it is designed to support entries from multiple
// processes and still record the UkmEntry in the event that the remote process
// is exited. If the browser process crashes then all entries that haven't been
// saved to a log are lost.
//
// Notice: This currently only works within the browser process. Multi-process
//         is not implemented and changes need to be added to the startup
//         process of the desired process.
//
// Create a new UKM entry as so:
//
// std::unique_ptr<SingularUkmEntry<AdFrameLoad>> entry =
//    SingularUkmEntry<AdFrameLoad>::Create(source_id);
//
// {
//   SingularUkmEntry<AdFrameLoad>::EntryBuilder builder = entry->Builder();
//   builder->SetCpuTime_PeakWindowedPercent(cpu_time_pwp1);
//   builder->SetCpuTime_Total(total_cpu_time1);
// }
// {
//   SingularUkmEntry<AdFrameLoad>::EntryBuilder builder = entry->Builder();
//   builder->SetCpuTime_PeakWindowedPercent(cpu_time_pwp2);
//   builder->SetCpuTime_Total(total_cpu_time2);
// }
//
// In the example above, only cpu_time_pwp2 and total_cpu_time2 will be recorded
// by the UKM service when `entry` is destroyed. Destructor of `builder` will
// update the `entry`.
//
// Note:
// - Use arrow operator on the builder to access the underlying UkmEntry. This
//   will give access to UkmEntry's methods.
// - When a EntryBuilder is destroyed or goes out of scope, the corresponding
//   UkmEntry is committed as the latest to be recorded.
// - A SingularUkmEntry and the EntryBuilders created from it must be used on
//   the same sequence it was created.
// - The UkmEntry will not be recorded until the SingularUkmEntry is destroyed.
// - The SingularUkmEntry must outlive all EntryBuilder's created from it.
// - All desired metrics must be set by the EntryBuilder to be recorded.
//
// Wrapper class to associate an UkmEntry type with an interface and source id.
// Template UkmEntry is expected to have a base class of UkmEntryBuilderBase.
// See tools/metrics/ukm/ukm.xml for entry definitions.
template <typename UkmEntry>
class SingularUkmEntry {};

}  // namespace ukm

#endif  // COMPONENTS_UKM_SINGULAR_UKM_ENTRY_H_