blob: 82e53290d05535b88a4a3b3e66201101b6a3e0f6 [file] [log] [blame]
// Copyright 2014 The Chromium 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 COMPONENTS_DATA_REDUCTION_PROXY_CORE_BROWSER_DATA_REDUCTION_PROXY_COMPRESSION_STATS_H_
#define COMPONENTS_DATA_REDUCTION_PROXY_CORE_BROWSER_DATA_REDUCTION_PROXY_COMPRESSION_STATS_H_
#include <stddef.h>
#include <stdint.h>
#include <map>
#include <memory>
#include <string>
#include <unordered_map>
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "base/threading/thread_checker.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_metrics.h"
#include "components/data_reduction_proxy/core/browser/db_data_owner.h"
#include "components/data_reduction_proxy/core/common/data_reduction_proxy_pref_names.h"
#include "components/data_use_measurement/core/data_use_user_data.h"
#include "components/prefs/pref_member.h"
class PrefService;
namespace base {
class ListValue;
class Value;
}
namespace data_reduction_proxy {
class DataReductionProxyService;
class DataUsageBucket;
class PerSiteDataUsage;
// These values are persisted to logs. Entries should not be renumbered and
// numeric values should never be reused.
//
// A Java counterpart will be generated for this enum.
// GENERATED_JAVA_ENUM_PACKAGE: (
// org.chromium.chrome.browser.preferences.datareduction)
enum class DataReductionProxySavingsClearedReason {
SYSTEM_CLOCK_MOVED_BACK,
PREFS_PARSE_ERROR,
USER_ACTION_EXTENSION,
USER_ACTION_SETTINGS_MENU,
USER_ACTION_DELETE_BROWSING_HISTORY,
// NOTE: always keep this entry at the end. Add new result types only
// immediately above this line. Make sure to update the corresponding
// histogram enum accordingly.
REASON_COUNT,
};
// Data reduction proxy delayed pref service reduces the number calls to pref
// service by storing prefs in memory and writing to the given PrefService after
// |delay| amount of time. If |delay| is zero, the delayed pref service writes
// directly to the PrefService and does not store the prefs in memory. All
// prefs must be stored and read on the UI thread.
class DataReductionProxyCompressionStats {
public:
typedef std::unordered_map<std::string, std::unique_ptr<PerSiteDataUsage>>
SiteUsageMap;
// Collects and store data usage and compression statistics. Basic data usage
// stats are stored in browser preferences. More detailed stats broken down
// by site and internet type are stored in |DataReductionProxyStore|.
//
// To store basic stats, it constructs a data reduction proxy delayed pref
// service object using |pref_service|. Writes prefs to |pref_service| after
// |delay| and stores them in |pref_map_| and |list_pref_map| between writes.
// If |delay| is zero, writes directly to the PrefService and does not store
// in the maps.
DataReductionProxyCompressionStats(DataReductionProxyService* service,
PrefService* pref_service,
const base::TimeDelta& delay);
~DataReductionProxyCompressionStats();
// Records detailed data usage broken down by |mime_type|. Also records daily
// data savings statistics to prefs and reports data savings UMA. |data_used|
// and |original_size| are measured in bytes.
void RecordDataUseWithMimeType(
int64_t compressed_size,
int64_t original_size,
bool data_reduction_proxy_enabled,
DataReductionProxyRequestType request_type,
const std::string& mime_type,
bool is_user_traffic,
data_use_measurement::DataUseUserData::DataUseContentType content_type,
int32_t service_hash_code);
// Record data usage and original size of request broken down by host.
// |original_request_size| and |data_used| are in bytes. |time| is the time at
// which the data usage occurred. This method should be called in real time,
// so |time| is expected to be |Time::Now()|.
void RecordDataUseByHost(const std::string& data_usage_host,
int64_t original_request_size,
int64_t data_used,
const base::Time time);
// Creates a |Value| summary of the persistent state of the network
// statistics.
// Must be called on the UI thread.
std::unique_ptr<base::Value> HistoricNetworkStatsInfoToValue();
// Creates a |Value| summary of the the session network statistics.
// Must be called on the UI thread.
std::unique_ptr<base::Value> SessionNetworkStatsInfoToValue() const;
// Returns the time in milliseconds since epoch that the last update was made
// to the daily original and received content lengths.
int64_t GetLastUpdateTime();
// Resets daily content length statistics.
void ResetStatistics();
// Clears all data saving statistics for the given |reason|.
void ClearDataSavingStatistics(DataReductionProxySavingsClearedReason reason);
// Returns the total size of all HTTP content received from the network.
int64_t GetHttpReceivedContentLength();
// Returns the value the total original size of all HTTP content received from
// the network.
int64_t GetHttpOriginalContentLength();
// Returns a list of all the daily content lengths.
ContentLengthList GetDailyContentLengths(const char* pref_name);
// Returns aggregate received and original content lengths over the specified
// number of days, as well as the time these stats were last updated.
void GetContentLengths(unsigned int days,
int64_t* original_content_length,
int64_t* received_content_length,
int64_t* last_update_time);
// Calls |get_data_usage_callback| with full data usage history. In-memory
// data usage stats are flushed to storage before querying for full history.
// An empty vector will be returned if "data_usage_reporting.enabled" pref is
// not enabled or if called immediately after enabling the pref before
// in-memory stats could be initialized from storage. Data usage is sorted
// chronologically with the last entry corresponding to |base::Time::Now()|.
void GetHistoricalDataUsage(
const HistoricalDataUsageCallback& get_data_usage_callback);
// Deletes browsing history from storage and memory for the given time
// range. Currently, this method deletes all data usage for the given range.
void DeleteBrowsingHistory(const base::Time& start, const base::Time& end);
// Callback from loading detailed data usage. Initializes in memory data
// structures used to collect data usage. |data_usage| contains the data usage
// for the last stored interval.
void OnCurrentDataUsageLoaded(std::unique_ptr<DataUsageBucket> data_usage);
// Sets the value of |prefs::kDataUsageReportingEnabled| to |enabled|.
// Initializes data usage statistics in memory when pref is enabled and
// persists data usage to memory when pref is disabled.
void SetDataUsageReportingEnabled(bool enabled);
// Returns |data_usage_map_|.
const DataReductionProxyCompressionStats::SiteUsageMap&
DataUsageMapForTesting() const {
return data_usage_map_;
}
private:
// Enum to track the state of loading data usage from storage.
enum CurrentDataUsageLoadStatus { NOT_LOADED = 0, LOADING = 1, LOADED = 2 };
friend class DataReductionProxyCompressionStatsTest;
typedef std::map<const char*, int64_t> DataReductionProxyPrefMap;
typedef std::unordered_map<const char*, std::unique_ptr<base::ListValue>>
DataReductionProxyListPrefMap;
class DailyContentLengthUpdate;
class DailyDataSavingUpdate;
// Loads all data_reduction_proxy::prefs into the |pref_map_| and
// |list_pref_map_|.
void Init();
// Gets the value of |pref| from the pref service and adds it to the
// |pref_map|.
void InitInt64Pref(const char* pref);
// Gets the value of |pref| from the pref service and adds it to the
// |list_pref_map|.
void InitListPref(const char* pref);
void OnUpdateContentLengths();
// Gets the int64_t pref at |pref_path| from the |DataReductionProxyPrefMap|.
int64_t GetInt64(const char* pref_path);
// Updates the pref value in the |DataReductionProxyPrefMap| map.
// The pref is later written to |pref service_|.
void SetInt64(const char* pref_path, int64_t pref_value);
// Increases the pref value in the |DataReductionProxyPrefMap| map.
// The pref is later written to |pref service_|.
void IncreaseInt64Pref(const char* pref_path, int64_t delta);
// Gets the pref list at |pref_path| from the |DataReductionProxyPrefMap|.
base::ListValue* GetList(const char* pref_path);
// Writes the prefs stored in |DataReductionProxyPrefMap| and
// |DataReductionProxyListPrefMap| to |pref_service|.
void WritePrefs();
// Starts a timer (if necessary) to write prefs in |kMinutesBetweenWrites| to
// the |pref_service|.
void DelayedWritePrefs();
// Copies the values at each index of |from_list| to the same index in
// |to_list|.
void TransferList(const base::ListValue& from_list,
base::ListValue* to_list);
// Records content length updates to prefs.
void RecordRequestSizePrefs(int64_t compressed_size,
int64_t original_size,
bool with_data_reduction_proxy_enabled,
DataReductionProxyRequestType request_type,
const std::string& mime_type,
const base::Time& now);
void IncrementDailyUmaPrefs(int64_t original_size,
int64_t received_size,
const char* original_size_pref,
const char* received_size_pref,
bool data_reduction_proxy_enabled,
const char* original_size_with_proxy_enabled_pref,
const char* recevied_size_with_proxy_enabled_pref,
bool via_data_reduction_proxy,
const char* original_size_via_proxy_pref,
const char* received_size_via_proxy_pref);
// Persists the in memory data usage information to storage and clears all
// in-memory data usage. Do not call this method unless |data_usage_loaded_|
// is |LOADED|.
void PersistDataUsage();
// Deletes all historical data usage from storage and memory. This method
// should not be called when |current_data_usage_load_status_| is |LOADING|.
void DeleteHistoricalDataUsage();
// Actual implementation of |GetHistoricalDataUsage|. This helper method
// explicitly passes |base::Time::Now()| to make testing easier.
void GetHistoricalDataUsageImpl(
const HistoricalDataUsageCallback& get_data_usage_callback,
const base::Time& now);
// Called when |prefs::kDataUsageReportingEnabled| pref values changes.
// Initializes data usage statistics in memory when pref is enabled and
// persists data usage to memory when pref is disabled.
void OnDataUsageReportingPrefChanged();
// Initialize the weekly data use prefs for the current week, and records the
// weekly aggregate data use histograms.
void InitializeWeeklyAggregateDataUse(const base::Time& now);
// Records |data_used_kb| to the current week data use pref. |is_user_request|
// indicates if this is user-initiated traffic or chrome services traffic, and
// |service_hash_code| uniquely identifies the corresponding chrome service.
void RecordWeeklyAggregateDataUse(
const base::Time& now,
int32_t data_used_kb,
bool is_user_request,
data_use_measurement::DataUseUserData::DataUseContentType content_type,
int32_t service_hash_code);
// Normalizes the hostname for data usage attribution. Returns a substring
// without the protocol.
// Example: "http://www.finance.google.com" -> "www.finance.google.com"
static std::string NormalizeHostname(const std::string& host);
DataReductionProxyService* service_;
PrefService* pref_service_;
const base::TimeDelta delay_;
DataReductionProxyPrefMap pref_map_;
DataReductionProxyListPrefMap list_pref_map_;
BooleanPrefMember data_usage_reporting_enabled_;
// Maintains detailed data usage for current interval.
SiteUsageMap data_usage_map_;
// Time when |data_usage_map_| was last updated. Contains NULL time if
// |data_usage_map_| does not have any data. This could happen either because
// current data usage has not yet been loaded from storage, or because
// no data usage has ever been recorded.
base::Time data_usage_map_last_updated_;
// Tracks whether |data_usage_map_| has changes that have not yet been
// persisted to storage.
bool data_usage_map_is_dirty_;
// Total size of all content that has been received over the network.
int64_t session_total_received_;
// Total original size of all content before it was proxied.
int64_t session_total_original_;
// Tracks state of loading data usage from storage.
CurrentDataUsageLoadStatus current_data_usage_load_status_;
base::OneShotTimer pref_writer_timer_;
base::ThreadChecker thread_checker_;
base::WeakPtrFactory<DataReductionProxyCompressionStats> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(DataReductionProxyCompressionStats);
};
} // namespace data_reduction_proxy
#endif // COMPONENTS_DATA_REDUCTION_PROXY_CORE_BROWSER_DATA_REDUCTION_PROXY_COMPRESSION_STATS_H_