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 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163
|
// Copyright 2019 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_ANDROID_USAGE_STATS_USAGE_STATS_DATABASE_H_
#define CHROME_BROWSER_ANDROID_USAGE_STATS_USAGE_STATS_DATABASE_H_
#include <map>
#include <memory>
#include <string>
#include <vector>
#include "base/containers/flat_set.h"
#include "base/containers/queue.h"
#include "base/functional/callback_forward.h"
#include "base/memory/weak_ptr.h"
#include "base/time/time.h"
#include "components/leveldb_proto/public/proto_database.h"
class Profile;
namespace usage_stats {
class WebsiteEvent;
class Suspension;
class TokenMapping;
using leveldb_proto::ProtoDatabase;
// Stores website events, suspensions and token to fully-qualified domain name
// (FQDN) mappings in LevelDB.
class UsageStatsDatabase {
public:
enum class Error { kNoError, kUnknownError };
using EventsCallback =
base::OnceCallback<void(Error, std::vector<WebsiteEvent>)>;
using SuspensionsCallback =
base::OnceCallback<void(Error, std::vector<std::string>)>;
using TokenMap = std::map<std::string, std::string>;
using TokenMappingsCallback = base::OnceCallback<void(Error, TokenMap)>;
using StatusCallback = base::OnceCallback<void(Error)>;
// Digital Wellbeing doesn't show activity older than a week, so 7 days is the
// max age for event retention.
constexpr static int EXPIRY_THRESHOLD_DAYS = 7;
// Initializes the database with user |profile|.
explicit UsageStatsDatabase(Profile* profile);
UsageStatsDatabase(const UsageStatsDatabase&) = delete;
UsageStatsDatabase& operator=(const UsageStatsDatabase&) = delete;
~UsageStatsDatabase();
void GetAllEvents(EventsCallback callback);
// Get all events in range between |startTime| (inclusive) and |endTime|
// (exclusive) at second-level granularity.
void QueryEventsInRange(base::Time startTime,
base::Time endTime,
EventsCallback callback);
void AddEvents(std::vector<WebsiteEvent> events, StatusCallback callback);
void DeleteAllEvents(StatusCallback callback);
// Delete all events in range between |startTime| (inclusive) and
// |endTime| (exclusive) at second-level granularity.
void DeleteEventsInRange(base::Time startTime,
base::Time endTime,
StatusCallback callback);
void DeleteEventsWithMatchingDomains(base::flat_set<std::string> domains,
StatusCallback callback);
// Delete events older than EXPIRY_THRESHOLD_DAYS.
void ExpireEvents(base::Time now);
void GetAllSuspensions(SuspensionsCallback callback);
// Persists all the suspensions in |domains| and deletes any suspensions *not*
// in |domains|.
void SetSuspensions(base::flat_set<std::string> domains,
StatusCallback callback);
void GetAllTokenMappings(TokenMappingsCallback callback);
// Persists all the mappings in |mappings| and deletes any mappings *not* in
// |mappings|. The map's key is the token, and its value is the FQDN.
void SetTokenMappings(TokenMap mappings, StatusCallback callback);
protected:
// For testing only.
UsageStatsDatabase(
std::unique_ptr<ProtoDatabase<WebsiteEvent>> website_event_db,
std::unique_ptr<ProtoDatabase<Suspension>> suspension_db,
std::unique_ptr<ProtoDatabase<TokenMapping>> token_mapping_db);
private:
void InitializeDBs();
void OnWebsiteEventInitDone(bool retry,
leveldb_proto::Enums::InitStatus status);
void OnSuspensionInitDone(bool retry,
leveldb_proto::Enums::InitStatus status);
void OnTokenMappingInitDone(bool retry,
leveldb_proto::Enums::InitStatus status);
void OnWebsiteEventExpiryDone(Error error);
void OnUpdateEntries(StatusCallback callback, bool isSuccess);
void OnLoadEntriesForGetAllEvents(
EventsCallback callback,
bool isSuccess,
std::unique_ptr<std::vector<WebsiteEvent>> stats);
void OnLoadEntriesForQueryEventsInRange(
EventsCallback callback,
bool isSuccess,
std::unique_ptr<std::map<std::string, WebsiteEvent>> event_map);
void OnLoadEntriesForDeleteEventsInRange(
StatusCallback callback,
bool isSuccess,
std::unique_ptr<std::map<std::string, WebsiteEvent>> event_map);
void OnLoadEntriesForGetAllSuspensions(
SuspensionsCallback callback,
bool isSuccess,
std::unique_ptr<std::vector<Suspension>> suspensions);
void OnLoadEntriesForGetAllTokenMappings(
TokenMappingsCallback callback,
bool isSuccess,
std::unique_ptr<std::vector<TokenMapping>> mappings);
std::unique_ptr<ProtoDatabase<WebsiteEvent>> website_event_db_;
std::unique_ptr<ProtoDatabase<Suspension>> suspension_db_;
std::unique_ptr<ProtoDatabase<TokenMapping>> token_mapping_db_;
// Track initialization state of proto databases.
bool website_event_db_initialized_;
bool suspension_db_initialized_;
bool token_mapping_db_initialized_;
// Store callbacks for delayed execution once database is initialized.
base::queue<base::OnceClosure> website_event_db_callbacks_;
base::queue<base::OnceClosure> suspension_db_callbacks_;
base::queue<base::OnceClosure> token_mapping_db_callbacks_;
base::WeakPtrFactory<UsageStatsDatabase> weak_ptr_factory_{this};
};
} // namespace usage_stats
#endif // CHROME_BROWSER_ANDROID_USAGE_STATS_USAGE_STATS_DATABASE_H_
|