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
|
// Copyright 2025 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_ACTOR_AGGREGATED_JOURNAL_H_
#define CHROME_BROWSER_ACTOR_AGGREGATED_JOURNAL_H_
#include <string>
#include <string_view>
#include <vector>
#include "base/containers/ring_buffer.h"
#include "base/containers/span.h"
#include "base/memory/safe_ref.h"
#include "base/memory/weak_ptr.h"
#include "base/observer_list.h"
#include "base/observer_list_types.h"
#include "base/supports_user_data.h"
#include "base/types/pass_key.h"
#include "chrome/browser/actor/task_id.h"
#include "chrome/common/actor.mojom.h"
#include "content/public/browser/render_frame_host.h"
#include "url/gurl.h"
namespace actor {
// A class that amalgamates all the journal entries from various RenderFrames.
class AggregatedJournal {
public:
AggregatedJournal();
~AggregatedJournal();
// Journal entry
struct Entry {
std::string url;
std::optional<std::vector<uint8_t>> jpg_screenshot;
std::optional<std::vector<uint8_t>> annotated_page_content;
mojom::JournalEntryPtr data;
Entry(const std::string& location, mojom::JournalEntryPtr data);
~Entry();
};
// A pending async journal entry.
class PendingAsyncEntry {
public:
// Creation of the event is only from the AggregatedJournal itself. Use
// `AggregatedJournal::CreatePendingAsyncEntry` to create this object.
PendingAsyncEntry(base::PassKey<AggregatedJournal>,
base::SafeRef<AggregatedJournal> journal,
TaskId task_id,
mojom::JournalTrack track,
std::string_view event_name);
~PendingAsyncEntry();
// End an pending entry with additional details. This can only be called
// once and will be automatically called from the destructor if it hasn't
// been called.
void EndEntry(std::string_view details);
AggregatedJournal& GetJournal();
TaskId GetTaskId();
private:
base::PassKey<AggregatedJournal> pass_key_;
bool terminated_ = false;
base::SafeRef<AggregatedJournal> journal_;
TaskId task_id_;
mojom::JournalTrack track_;
std::string event_name_;
};
// Observing class for new entries.
class Observer : public base::CheckedObserver {
public:
virtual void WillAddJournalEntry(const Entry& entry) = 0;
};
using EntryBuffer = base::RingBuffer<std::unique_ptr<Entry>, 20>;
void AddObserver(Observer* observer);
void RemoveObserver(Observer* observer);
// Create an async entry. This will log a Begin Entry event and when the
// PendingAsyncEntry object is destroyed the End Entry will be logged.
std::unique_ptr<PendingAsyncEntry> CreatePendingAsyncEntry(
const GURL& url,
TaskId task_id,
mojom::JournalTrack track,
std::string_view event_name,
std::string_view details);
// Log an instant event.
void Log(const GURL& url,
TaskId task_id,
mojom::JournalTrack track,
std::string_view event_name,
std::string_view details);
// Screenshots need to be an instant event with a custom event name to be
// decoded in perfetto.
void LogScreenshot(const GURL& url,
TaskId task_id,
std::string_view mime_type,
base::span<const uint8_t> data);
// Log Annotated Page Content.
void LogAnnotatedPageContent(const GURL& url,
TaskId task_id,
base::span<const uint8_t> data);
void EnsureJournalBound(content::RenderFrameHost& rfh);
void AppendJournalEntries(content::RenderFrameHost* rfh,
std::vector<mojom::JournalEntryPtr> entries);
EntryBuffer::Iterator Items() { return entries_.Begin(); }
base::SafeRef<AggregatedJournal> GetSafeRef();
void AddEndEvent(base::PassKey<AggregatedJournal>,
TaskId task_id,
mojom::JournalTrack track,
const std::string& event_name,
std::string_view details);
private:
void AddEntry(std::unique_ptr<Entry>);
base::ObserverList<Observer> observers_;
EntryBuffer entries_;
base::WeakPtrFactory<AggregatedJournal> weak_ptr_factory_{this};
};
} // namespace actor
#endif // CHROME_BROWSER_ACTOR_AGGREGATED_JOURNAL_H_
|