#ifndef ANDROID_WEBVIEW_BROWSER_METRICS_AW_METRICS_SERVICE_CLIENT_H_
#define ANDROID_WEBVIEW_BROWSER_METRICS_AW_METRICS_SERVICE_CLIENT_H_
#include <memory>
#include <string>
#include <string_view>
#include "android_webview/browser/lifecycle/webview_app_state_observer.h"
#include "base/functional/callback_forward.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/scoped_refptr.h"
#include "base/memory/weak_ptr.h"
#include "base/metrics/field_trial.h"
#include "base/no_destructor.h"
#include "base/scoped_multi_source_observation.h"
#include "base/scoped_observation.h"
#include "base/sequence_checker.h"
#include "base/time/time.h"
#include "components/metrics/enabled_state_provider.h"
#include "components/metrics/metrics_log_uploader.h"
#include "components/metrics/metrics_service_client.h"
#include "components/metrics/persistent_synthetic_trial_observer.h"
#include "components/variations/synthetic_trial_registry.h"
#include "components/version_info/android/channel_getter.h"
#include "content/public/browser/render_process_host_creation_observer.h"
#include "content/public/browser/render_process_host_observer.h"
#include "content/public/browser/web_contents.h"
class PrefRegistrySimple;
class PrefService;
namespace metrics {
class MetricsStateManager;
}
namespace android_webview {
extern const char kCrashpadHistogramAllocatorName[];
class AwMetricsServiceClient
: public metrics::MetricsServiceClient,
public metrics::EnabledStateProvider,
public content::RenderProcessHostCreationObserver,
public content::RenderProcessHostObserver,
public WebViewAppStateObserver {
friend class base::NoDestructor<AwMetricsServiceClient>;
public:
class Delegate {
public:
Delegate();
virtual ~Delegate();
Delegate(const Delegate&) = delete;
Delegate& operator=(const Delegate&) = delete;
Delegate(Delegate&&) = delete;
Delegate& operator=(Delegate&&) = delete;
virtual void RegisterAdditionalMetricsProviders(
metrics::MetricsService* service) = 0;
virtual void AddWebViewAppStateObserver(
WebViewAppStateObserver* observer) = 0;
virtual bool HasAwContentsEverCreated() const = 0;
};
static AwMetricsServiceClient* GetInstance();
static void SetInstance(
std::unique_ptr<AwMetricsServiceClient> aw_metrics_service_client);
static void RegisterMetricsPrefs(PrefRegistrySimple* registry);
static base::FilePath GetNoBackupFilesDir();
explicit AwMetricsServiceClient(std::unique_ptr<Delegate> delegate);
AwMetricsServiceClient(const AwMetricsServiceClient&) = delete;
AwMetricsServiceClient& operator=(const AwMetricsServiceClient&) = delete;
~AwMetricsServiceClient() override;
void Initialize(PrefService* pref_service);
void SetHaveMetricsConsent(bool user_consent, bool app_consent);
void SetFastStartupForTesting(bool fast_startup_for_testing);
void SetUploadIntervalForTesting(const base::TimeDelta& upload_interval);
bool IsConsentGiven() const override;
bool IsReportingEnabled() const override;
metrics::MetricsService* GetMetricsServiceIfStarted();
variations::SyntheticTrialRegistry* GetSyntheticTrialRegistry() override;
metrics::MetricsService* GetMetricsService() override;
void SetMetricsClientId(const std::string& client_id) override;
int32_t GetProduct() override;
std::string GetApplicationLocale() override;
const network_time::NetworkTimeTracker* GetNetworkTimeTracker() override;
bool GetBrand(std::string* brand_code) override;
metrics::SystemProfileProto::Channel GetChannel() override;
bool IsExtendedStableChannel() override;
std::string GetVersionString() override;
void MergeSubprocessHistograms() override;
void CollectFinalMetricsForLog(
const base::OnceClosure done_callback) override;
std::unique_ptr<metrics::MetricsLogUploader> CreateUploader(
const GURL& server_url,
const GURL& insecure_server_url,
std::string_view mime_type,
metrics::MetricsLogUploader::MetricServiceType service_type,
const metrics::MetricsLogUploader::UploadCallback& on_upload_complete)
override;
base::TimeDelta GetStandardUploadInterval() override;
bool ShouldStartUpFast() const override;
std::string GetAppPackageNameIfLoggable() override;
void OnWebContentsCreated(content::WebContents* web_contents);
void OnRenderProcessHostCreated(content::RenderProcessHost* host) override;
void RenderProcessExited(
content::RenderProcessHost* host,
const content::ChildProcessTerminationInfo& info) override;
void SetCollectFinalMetricsForLogClosureForTesting(base::OnceClosure closure);
void SetOnFinalMetricsCollectedListenerForTesting(
base::RepeatingClosure listener);
metrics::MetricsStateManager* metrics_state_manager() const {
return metrics_state_manager_.get();
}
enum class InstallerPackageType {
SYSTEM_APP,
GOOGLE_PLAY_STORE,
OTHER,
};
std::string GetAppPackageName();
virtual InstallerPackageType GetInstallerPackageType();
base::FilePath GetMetricsDir();
base::FilePath GetOldMetricsDirForTesting();
void SetUpMetricsDir();
void OnAppStateChanged(WebViewAppStateObserver::State state) override;
virtual bool ShouldApplyMetricsFiltering() const;
protected:
virtual int GetUnfilteredSampleRatePerMille() const;
virtual int GetSampleBucketValue() const;
virtual bool CanRecordPackageNameForAppType();
private:
bool IsReadyToStart() const;
void MaybeStartMetrics();
void RegisterForNotifications();
void RegisterMetricsProvidersAndInitState();
void OnApplicationNotIdle();
void OnDidStartLoading();
std::unique_ptr<metrics::MetricsStateManager> metrics_state_manager_;
std::unique_ptr<variations::SyntheticTrialRegistry> synthetic_trial_registry_;
metrics::PersistentSyntheticTrialObserver synthetic_trial_observer_;
base::ScopedObservation<variations::SyntheticTrialRegistry,
variations::SyntheticTrialObserver>
synthetic_trial_observation_{&synthetic_trial_observer_};
std::unique_ptr<metrics::MetricsService> metrics_service_;
base::ScopedMultiSourceObservation<content::RenderProcessHost,
content::RenderProcessHostObserver>
host_observation_{this};
raw_ptr<PrefService> pref_service_ = nullptr;
bool init_finished_ = false;
bool set_consent_finished_ = false;
bool user_consent_ = false;
bool app_consent_ = false;
bool is_client_id_forced_ = false;
bool fast_startup_for_testing_ = false;
bool did_start_metrics_ = false;
base::TimeDelta overridden_upload_interval_;
base::OnceClosure collect_final_metrics_for_log_closure_;
base::RepeatingClosure on_final_metrics_collected_listener_;
#if DCHECK_IS_ON()
bool did_start_metrics_with_consent_ = false;
#endif
SEQUENCE_CHECKER(sequence_checker_);
bool app_in_foreground_ = false;
base::Time time_created_;
std::unique_ptr<Delegate> delegate_;
base::FilePath metrics_dir_;
base::FilePath old_metrics_dir_;
base::WeakPtrFactory<AwMetricsServiceClient> weak_ptr_factory_{this};
};
}
#endif