metrics_service.cc 44 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140
  1. // Copyright 2014 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. //------------------------------------------------------------------------------
  5. // Description of a MetricsService instance's life cycle.
  6. //
  7. // OVERVIEW
  8. //
  9. // A MetricsService instance is typically created at application startup. It is
  10. // the central controller for the acquisition of log data, and the automatic
  11. // transmission of that log data to an external server. Its major job is to
  12. // manage logs, grouping them for transmission, and transmitting them. As part
  13. // of its grouping, MS finalizes logs by including some just-in-time gathered
  14. // memory statistics, snapshotting the current stats of numerous histograms,
  15. // closing the logs, translating to protocol buffer format, and compressing the
  16. // results for transmission. Transmission includes submitting a compressed log
  17. // as data in a URL-post, and retransmitting (or retaining at process
  18. // termination) if the attempted transmission failed. Retention across process
  19. // terminations is done using the PrefServices facilities. The retained logs
  20. // (the ones that never got transmitted) are compressed and base64-encoded
  21. // before being persisted.
  22. //
  23. // Logs fall into one of two categories: "initial logs," and "ongoing logs."
  24. // There is at most one initial log sent for each complete run of Chrome (from
  25. // startup, to browser shutdown). An initial log is generally transmitted some
  26. // short time (1 minute?) after startup, and includes stats such as recent crash
  27. // info, the number and types of plugins, etc. The external server's response
  28. // to the initial log conceptually tells this MS if it should continue
  29. // transmitting logs (during this session). The server response can actually be
  30. // much more detailed, and always includes (at a minimum) how often additional
  31. // ongoing logs should be sent.
  32. //
  33. // After the above initial log, a series of ongoing logs will be transmitted.
  34. // The first ongoing log actually begins to accumulate information stating when
  35. // the MS was first constructed. Note that even though the initial log is
  36. // commonly sent a full minute after startup, the initial log does not include
  37. // much in the way of user stats. The most common interlog period (delay)
  38. // is 30 minutes. That time period starts when the first user action causes a
  39. // logging event. This means that if there is no user action, there may be long
  40. // periods without any (ongoing) log transmissions. Ongoing logs typically
  41. // contain very detailed records of user activities (ex: opened tab, closed
  42. // tab, fetched URL, maximized window, etc.) In addition, just before an
  43. // ongoing log is closed out, a call is made to gather memory statistics. Those
  44. // memory statistics are deposited into a histogram, and the log finalization
  45. // code is then called. In the finalization, a call to a Histogram server
  46. // acquires a list of all local histograms that have been flagged for upload
  47. // to the UMA server. The finalization also acquires the most recent number
  48. // of page loads, along with any counts of renderer or plugin crashes.
  49. //
  50. // When the browser shuts down, there will typically be a fragment of an ongoing
  51. // log that has not yet been transmitted. At shutdown time, that fragment is
  52. // closed (including snapshotting histograms), and persisted, for potential
  53. // transmission during a future run of the product.
  54. //
  55. // There are two slightly abnormal shutdown conditions. There is a
  56. // "disconnected scenario," and a "really fast startup and shutdown" scenario.
  57. // In the "never connected" situation, the user has (during the running of the
  58. // process) never established an internet connection. As a result, attempts to
  59. // transmit the initial log have failed, and a lot(?) of data has accumulated in
  60. // the ongoing log (which didn't yet get closed, because there was never even a
  61. // contemplation of sending it). There is also a kindred "lost connection"
  62. // situation, where a loss of connection prevented an ongoing log from being
  63. // transmitted, and a (still open) log was stuck accumulating a lot(?) of data,
  64. // while the earlier log retried its transmission. In both of these
  65. // disconnected situations, two logs need to be, and are, persistently stored
  66. // for future transmission.
  67. //
  68. // The other unusual shutdown condition, termed "really fast startup and
  69. // shutdown," involves the deliberate user termination of the process before
  70. // the initial log is even formed or transmitted. In that situation, no logging
  71. // is done, but the historical crash statistics remain (unlogged) for inclusion
  72. // in a future run's initial log. (i.e., we don't lose crash stats).
  73. //
  74. // With the above overview, we can now describe the state machine's various
  75. // states, based on the State enum specified in the state_ member. Those states
  76. // are:
  77. //
  78. // CONSTRUCTED, // Constructor was called.
  79. // INITIALIZED, // InitializeMetricsRecordingState() was called.
  80. // INIT_TASK_SCHEDULED, // Waiting for deferred init tasks to finish.
  81. // INIT_TASK_DONE, // Waiting for timer to send initial log.
  82. // SENDING_LOGS, // Sending logs and creating new ones when we run out.
  83. //
  84. // In more detail, we have:
  85. //
  86. // INIT_TASK_SCHEDULED, // Waiting for deferred init tasks to finish.
  87. // Typically about 30 seconds after startup, a task is sent to a second thread
  88. // (the file thread) to perform deferred (lower priority and slower)
  89. // initialization steps such as getting the list of plugins. That task will
  90. // (when complete) make an async callback (via a Task) to indicate the
  91. // completion.
  92. //
  93. // INIT_TASK_DONE, // Waiting for timer to send initial log.
  94. // The callback has arrived, and it is now possible for an initial log to be
  95. // created. This callback typically arrives back less than one second after
  96. // the deferred init task is dispatched.
  97. //
  98. // SENDING_LOGS, // Sending logs an creating new ones when we run out.
  99. // Logs from previous sessions have been loaded, and initial logs have been
  100. // created (an optional stability log and the first metrics log). We will
  101. // send all of these logs, and when run out, we will start cutting new logs
  102. // to send. We will also cut a new log if we expect a shutdown.
  103. //
  104. // The progression through the above states is simple, and sequential.
  105. // States proceed from INITIAL to SENDING_LOGS, and remain in the latter until
  106. // shutdown.
  107. //
  108. // Also note that whenever we successfully send a log, we mirror the list
  109. // of logs into the PrefService. This ensures that IF we crash, we won't start
  110. // up and retransmit our old logs again.
  111. //
  112. // Due to race conditions, it is always possible that a log file could be sent
  113. // twice. For example, if a log file is sent, but not yet acknowledged by
  114. // the external server, and the user shuts down, then a copy of the log may be
  115. // saved for re-transmission. These duplicates could be filtered out server
  116. // side, but are not expected to be a significant problem.
  117. //
  118. //
  119. //------------------------------------------------------------------------------
  120. #include "components/metrics/metrics_service.h"
  121. #include <stddef.h>
  122. #include <algorithm>
  123. #include <memory>
  124. #include <utility>
  125. #include "base/bind.h"
  126. #include "base/callback.h"
  127. #include "base/callback_list.h"
  128. #include "base/location.h"
  129. #include "base/metrics/histogram_base.h"
  130. #include "base/metrics/histogram_flattener.h"
  131. #include "base/metrics/histogram_functions.h"
  132. #include "base/metrics/histogram_macros.h"
  133. #include "base/metrics/histogram_samples.h"
  134. #include "base/metrics/persistent_histogram_allocator.h"
  135. #include "base/metrics/statistics_recorder.h"
  136. #include "base/process/process_handle.h"
  137. #include "base/rand_util.h"
  138. #include "base/strings/string_piece.h"
  139. #include "base/task/single_thread_task_runner.h"
  140. #include "base/threading/sequenced_task_runner_handle.h"
  141. #include "base/time/time.h"
  142. #include "build/build_config.h"
  143. #include "build/chromeos_buildflags.h"
  144. #include "components/metrics/clean_exit_beacon.h"
  145. #include "components/metrics/environment_recorder.h"
  146. #include "components/metrics/field_trials_provider.h"
  147. #include "components/metrics/metrics_log.h"
  148. #include "components/metrics/metrics_log_manager.h"
  149. #include "components/metrics/metrics_log_uploader.h"
  150. #include "components/metrics/metrics_pref_names.h"
  151. #include "components/metrics/metrics_rotation_scheduler.h"
  152. #include "components/metrics/metrics_service_client.h"
  153. #include "components/metrics/metrics_state_manager.h"
  154. #include "components/metrics/persistent_system_profile.h"
  155. #include "components/metrics/stability_metrics_provider.h"
  156. #include "components/metrics/url_constants.h"
  157. #include "components/prefs/pref_registry_simple.h"
  158. #include "components/prefs/pref_service.h"
  159. #include "components/variations/entropy_provider.h"
  160. #if BUILDFLAG(IS_CHROMEOS_ASH)
  161. #include "components/metrics/structured/neutrino_logging.h" // nogncheck
  162. #endif // BUILDFLAG(IS_CHROMEOS_ASH)
  163. namespace metrics {
  164. namespace {
  165. // Used to mark histogram samples as reported so that they are not included in
  166. // the next log. A histogram's snapshot samples are simply discarded/ignored
  167. // when attempting to record them through this |HistogramFlattener|.
  168. class DiscardingFlattener : public base::HistogramFlattener {
  169. public:
  170. DiscardingFlattener() = default;
  171. DiscardingFlattener(const DiscardingFlattener&) = delete;
  172. DiscardingFlattener& operator=(const DiscardingFlattener&) = delete;
  173. ~DiscardingFlattener() override = default;
  174. void RecordDelta(const base::HistogramBase& histogram,
  175. const base::HistogramSamples& snapshot) override {
  176. // No-op. We discard the samples.
  177. }
  178. };
  179. // The delay, in seconds, after starting recording before doing expensive
  180. // initialization work.
  181. #if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_IOS)
  182. // On mobile devices, a significant portion of sessions last less than a minute.
  183. // Use a shorter timer on these platforms to avoid losing data.
  184. // TODO(dfalcantara): To avoid delaying startup, tighten up initialization so
  185. // that it occurs after the user gets their initial page.
  186. const int kInitializationDelaySeconds = 5;
  187. #else
  188. const int kInitializationDelaySeconds = 30;
  189. #endif
  190. // The browser last live timestamp is updated every 15 minutes.
  191. const int kUpdateAliveTimestampSeconds = 15 * 60;
  192. #if BUILDFLAG(IS_CHROMEOS_ASH)
  193. enum UserLogStoreState {
  194. kSetPostSendLogsState = 0,
  195. kSetPreSendLogsState = 1,
  196. kUnsetPostSendLogsState = 2,
  197. kUnsetPreSendLogsState = 3,
  198. kMaxValue = kUnsetPreSendLogsState,
  199. };
  200. void RecordUserLogStoreState(UserLogStoreState state) {
  201. base::UmaHistogramEnumeration("UMA.CrosPerUser.UserLogStoreState", state);
  202. }
  203. #endif // BUILDFLAG(IS_CHROMEOS_ASH)
  204. } // namespace
  205. // Determines whether the initial log should use the same logic as subsequent
  206. // logs when building it.
  207. const base::Feature kConsolidateMetricsServiceInitialLogLogic = {
  208. "ConsolidateMetricsServiceInitialLogLogic",
  209. base::FEATURE_DISABLED_BY_DEFAULT};
  210. // static
  211. void MetricsService::RegisterPrefs(PrefRegistrySimple* registry) {
  212. CleanExitBeacon::RegisterPrefs(registry);
  213. MetricsStateManager::RegisterPrefs(registry);
  214. MetricsLog::RegisterPrefs(registry);
  215. StabilityMetricsProvider::RegisterPrefs(registry);
  216. MetricsReportingService::RegisterPrefs(registry);
  217. registry->RegisterIntegerPref(prefs::kMetricsSessionID, -1);
  218. }
  219. MetricsService::MetricsService(MetricsStateManager* state_manager,
  220. MetricsServiceClient* client,
  221. PrefService* local_state)
  222. : reporting_service_(client, local_state),
  223. histogram_snapshot_manager_(this),
  224. state_manager_(state_manager),
  225. client_(client),
  226. local_state_(local_state),
  227. recording_state_(UNSET),
  228. test_mode_active_(false),
  229. state_(CONSTRUCTED),
  230. idle_since_last_transmission_(false),
  231. session_id_(-1) {
  232. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  233. DCHECK(state_manager_);
  234. DCHECK(client_);
  235. DCHECK(local_state_);
  236. RegisterMetricsProvider(
  237. std::make_unique<StabilityMetricsProvider>(local_state_));
  238. RegisterMetricsProvider(state_manager_->GetProvider());
  239. }
  240. MetricsService::~MetricsService() {
  241. DisableRecording();
  242. }
  243. void MetricsService::InitializeMetricsRecordingState() {
  244. DCHECK_EQ(CONSTRUCTED, state_);
  245. // The FieldTrialsProvider should be registered last. This ensures that
  246. // studies whose features are checked when providers add their information to
  247. // the log appear in the active field trials.
  248. RegisterMetricsProvider(std::make_unique<variations::FieldTrialsProvider>(
  249. client_->GetSyntheticTrialRegistry(), base::StringPiece()));
  250. reporting_service_.Initialize();
  251. InitializeMetricsState();
  252. base::RepeatingClosure upload_callback = base::BindRepeating(
  253. &MetricsService::StartScheduledUpload, self_ptr_factory_.GetWeakPtr());
  254. rotation_scheduler_ = std::make_unique<MetricsRotationScheduler>(
  255. upload_callback,
  256. // MetricsServiceClient outlives MetricsService, and
  257. // MetricsRotationScheduler is tied to the lifetime of |this|.
  258. base::BindRepeating(&MetricsServiceClient::GetUploadInterval,
  259. base::Unretained(client_)),
  260. client_->ShouldStartUpFastForTesting());
  261. // Init() has to be called after LogCrash() in order for LogCrash() to work.
  262. delegating_provider_.Init();
  263. state_ = INITIALIZED;
  264. }
  265. void MetricsService::Start() {
  266. HandleIdleSinceLastTransmission(false);
  267. EnableRecording();
  268. EnableReporting();
  269. }
  270. void MetricsService::StartRecordingForTests() {
  271. test_mode_active_ = true;
  272. EnableRecording();
  273. DisableReporting();
  274. }
  275. void MetricsService::StartUpdatingLastLiveTimestamp() {
  276. base::SequencedTaskRunnerHandle::Get()->PostDelayedTask(
  277. FROM_HERE,
  278. base::BindOnce(&MetricsService::UpdateLastLiveTimestampTask,
  279. self_ptr_factory_.GetWeakPtr()),
  280. base::Seconds(kUpdateAliveTimestampSeconds));
  281. }
  282. void MetricsService::Stop() {
  283. HandleIdleSinceLastTransmission(false);
  284. DisableReporting();
  285. DisableRecording();
  286. }
  287. void MetricsService::EnableReporting() {
  288. if (reporting_service_.reporting_active())
  289. return;
  290. reporting_service_.EnableReporting();
  291. StartSchedulerIfNecessary();
  292. }
  293. void MetricsService::DisableReporting() {
  294. reporting_service_.DisableReporting();
  295. }
  296. std::string MetricsService::GetClientId() const {
  297. return state_manager_->client_id();
  298. }
  299. void MetricsService::SetExternalClientId(const std::string& id) {
  300. state_manager_->SetExternalClientId(id);
  301. }
  302. bool MetricsService::WasLastShutdownClean() const {
  303. return state_manager_->clean_exit_beacon()->exited_cleanly();
  304. }
  305. void MetricsService::EnableRecording() {
  306. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  307. if (recording_state_ == ACTIVE)
  308. return;
  309. recording_state_ = ACTIVE;
  310. state_manager_->ForceClientIdCreation();
  311. client_->SetMetricsClientId(state_manager_->client_id());
  312. if (!log_manager_.current_log())
  313. OpenNewLog();
  314. delegating_provider_.OnRecordingEnabled();
  315. #if BUILDFLAG(IS_CHROMEOS_ASH)
  316. // This must be after OnRecordingEnabled() to ensure that the structured
  317. // logging has been enabled.
  318. metrics::structured::NeutrinoDevicesLogWithClientId(
  319. state_manager_->client_id(),
  320. metrics::structured::NeutrinoDevicesLocation::kEnableRecording);
  321. #endif // BUILDFLAG(IS_CHROMEOS_ASH)
  322. // Fill in the system profile in the log and persist it (to prefs, .pma
  323. // and crashpad). This includes running the providers so that information
  324. // like field trials and hardware info is provided. If Chrome crashes
  325. // before this log is completed, the .pma file will have this system
  326. // profile.
  327. RecordCurrentEnvironment(log_manager_.current_log(), /*complete=*/false);
  328. base::RemoveActionCallback(action_callback_);
  329. action_callback_ = base::BindRepeating(&MetricsService::OnUserAction,
  330. base::Unretained(this));
  331. base::AddActionCallback(action_callback_);
  332. enablement_observers_.Notify(/*enabled=*/true);
  333. }
  334. void MetricsService::DisableRecording() {
  335. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  336. if (recording_state_ == INACTIVE)
  337. return;
  338. recording_state_ = INACTIVE;
  339. base::RemoveActionCallback(action_callback_);
  340. delegating_provider_.OnRecordingDisabled();
  341. PushPendingLogsToPersistentStorage();
  342. enablement_observers_.Notify(/*enabled=*/false);
  343. }
  344. bool MetricsService::recording_active() const {
  345. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  346. return recording_state_ == ACTIVE;
  347. }
  348. bool MetricsService::reporting_active() const {
  349. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  350. return reporting_service_.reporting_active();
  351. }
  352. bool MetricsService::has_unsent_logs() const {
  353. return reporting_service_.metrics_log_store()->has_unsent_logs();
  354. }
  355. bool MetricsService::IsMetricsReportingEnabled() const {
  356. return state_manager_->IsMetricsReportingEnabled();
  357. }
  358. void MetricsService::RecordDelta(const base::HistogramBase& histogram,
  359. const base::HistogramSamples& snapshot) {
  360. log_manager_.current_log()->RecordHistogramDelta(histogram.histogram_name(),
  361. snapshot);
  362. }
  363. void MetricsService::HandleIdleSinceLastTransmission(bool in_idle) {
  364. // If there wasn't a lot of action, maybe the computer was asleep, in which
  365. // case, the log transmissions should have stopped. Here we start them up
  366. // again.
  367. if (!in_idle && idle_since_last_transmission_)
  368. StartSchedulerIfNecessary();
  369. idle_since_last_transmission_ = in_idle;
  370. }
  371. void MetricsService::OnApplicationNotIdle() {
  372. if (recording_state_ == ACTIVE)
  373. HandleIdleSinceLastTransmission(false);
  374. }
  375. #if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_IOS)
  376. void MetricsService::OnAppEnterBackground(bool keep_recording_in_background) {
  377. is_in_foreground_ = false;
  378. if (!keep_recording_in_background) {
  379. rotation_scheduler_->Stop();
  380. reporting_service_.Stop();
  381. }
  382. state_manager_->LogHasSessionShutdownCleanly(true);
  383. // Schedule a write, which happens on a different thread.
  384. local_state_->CommitPendingWrite();
  385. // Give providers a chance to persist histograms as part of being
  386. // backgrounded.
  387. delegating_provider_.OnAppEnterBackground();
  388. // At this point, there's no way of knowing when the process will be
  389. // killed, so this has to be treated similar to a shutdown, closing and
  390. // persisting all logs. Unlinke a shutdown, the state is primed to be ready
  391. // to continue logging and uploading if the process does return.
  392. if (recording_active() && state_ >= SENDING_LOGS) {
  393. PushPendingLogsToPersistentStorage();
  394. // Persisting logs closes the current log, so start recording a new log
  395. // immediately to capture any background work that might be done before the
  396. // process is killed.
  397. OpenNewLog();
  398. }
  399. }
  400. void MetricsService::OnAppEnterForeground(bool force_open_new_log) {
  401. is_in_foreground_ = true;
  402. state_manager_->LogHasSessionShutdownCleanly(false);
  403. StartSchedulerIfNecessary();
  404. if (force_open_new_log && recording_active() && state_ >= SENDING_LOGS) {
  405. // Because state_ >= SENDING_LOGS, PushPendingLogsToPersistentStorage()
  406. // will close the log, allowing a new log to be opened.
  407. PushPendingLogsToPersistentStorage();
  408. OpenNewLog();
  409. }
  410. }
  411. #endif // BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_IOS)
  412. void MetricsService::LogCleanShutdown() {
  413. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  414. state_manager_->LogHasSessionShutdownCleanly(true);
  415. }
  416. void MetricsService::ClearSavedStabilityMetrics() {
  417. delegating_provider_.ClearSavedStabilityMetrics();
  418. // Stability metrics are stored in Local State prefs, so schedule a Local
  419. // State write to flush the updated prefs.
  420. local_state_->CommitPendingWrite();
  421. }
  422. void MetricsService::MarkCurrentHistogramsAsReported() {
  423. DiscardingFlattener flattener;
  424. base::HistogramSnapshotManager snapshot_manager(&flattener);
  425. base::StatisticsRecorder::PrepareDeltas(
  426. /*include_persistent=*/true, /*flags_to_set=*/base::Histogram::kNoFlags,
  427. /*required_flags=*/base::Histogram::kUmaTargetedHistogramFlag,
  428. &snapshot_manager);
  429. }
  430. #if BUILDFLAG(IS_CHROMEOS_ASH)
  431. void MetricsService::SetUserLogStore(
  432. std::unique_ptr<UnsentLogStore> user_log_store) {
  433. if (log_store()->has_alternate_ongoing_log_store())
  434. return;
  435. if (state_ >= SENDING_LOGS) {
  436. // Closes the current log so that a new log can be opened in the user log
  437. // store.
  438. PushPendingLogsToPersistentStorage();
  439. log_store()->SetAlternateOngoingLogStore(std::move(user_log_store));
  440. OpenNewLog();
  441. RecordUserLogStoreState(kSetPostSendLogsState);
  442. } else {
  443. // Initial log has not yet been created and flushing now would result in
  444. // incomplete information in the current log.
  445. //
  446. // Logs recorded before a user login will be appended to user logs. This
  447. // should not happen frequently.
  448. //
  449. // TODO(crbug/1264627): Look for a way to "pause" pre-login logs and flush
  450. // when INIT_TASK is done.
  451. log_store()->SetAlternateOngoingLogStore(std::move(user_log_store));
  452. RecordUserLogStoreState(kSetPreSendLogsState);
  453. }
  454. }
  455. void MetricsService::UnsetUserLogStore() {
  456. if (!log_store()->has_alternate_ongoing_log_store())
  457. return;
  458. if (state_ >= SENDING_LOGS) {
  459. PushPendingLogsToPersistentStorage();
  460. log_store()->UnsetAlternateOngoingLogStore();
  461. OpenNewLog();
  462. RecordUserLogStoreState(kUnsetPostSendLogsState);
  463. } else {
  464. // Fast startup and logout case. A call to |RecordCurrentHistograms()| is
  465. // made to flush all histograms into the current log and the log is
  466. // discarded. This is to prevent histograms captured during the user session
  467. // from leaking into local state logs.
  468. RecordCurrentHistograms();
  469. log_manager_.DiscardCurrentLog();
  470. log_store()->UnsetAlternateOngoingLogStore();
  471. RecordUserLogStoreState(kUnsetPreSendLogsState);
  472. }
  473. }
  474. bool MetricsService::HasUserLogStore() {
  475. return log_store()->has_alternate_ongoing_log_store();
  476. }
  477. void MetricsService::InitPerUserMetrics() {
  478. client_->InitPerUserMetrics();
  479. }
  480. absl::optional<bool> MetricsService::GetCurrentUserMetricsConsent() const {
  481. return client_->GetCurrentUserMetricsConsent();
  482. }
  483. absl::optional<std::string> MetricsService::GetCurrentUserId() const {
  484. return client_->GetCurrentUserId();
  485. }
  486. void MetricsService::UpdateCurrentUserMetricsConsent(
  487. bool user_metrics_consent) {
  488. client_->UpdateCurrentUserMetricsConsent(user_metrics_consent);
  489. }
  490. #endif // BUILDFLAG(IS_CHROMEOS_ASH)
  491. #if BUILDFLAG(IS_CHROMEOS)
  492. void MetricsService::ResetClientId() {
  493. // Pref must be cleared in order for ForceClientIdCreation to generate a new
  494. // client ID.
  495. local_state_->ClearPref(prefs::kMetricsClientID);
  496. state_manager_->ForceClientIdCreation();
  497. client_->SetMetricsClientId(state_manager_->client_id());
  498. }
  499. #endif // BUILDFLAG(IS_CHROMEOS)
  500. variations::SyntheticTrialRegistry*
  501. MetricsService::GetSyntheticTrialRegistry() {
  502. return client_->GetSyntheticTrialRegistry();
  503. }
  504. bool MetricsService::StageCurrentLogForTest() {
  505. CloseCurrentLog();
  506. MetricsLogStore* const log_store = reporting_service_.metrics_log_store();
  507. log_store->StageNextLog();
  508. if (!log_store->has_staged_log())
  509. return false;
  510. OpenNewLog();
  511. return true;
  512. }
  513. //------------------------------------------------------------------------------
  514. // private methods
  515. //------------------------------------------------------------------------------
  516. //------------------------------------------------------------------------------
  517. // Initialization methods
  518. void MetricsService::InitializeMetricsState() {
  519. SCOPED_UMA_HISTOGRAM_TIMER_MICROS("UMA.MetricsService.Initialize.Time");
  520. const int64_t buildtime = MetricsLog::GetBuildTime();
  521. const std::string version = client_->GetVersionString();
  522. bool version_changed = false;
  523. EnvironmentRecorder recorder(local_state_);
  524. int64_t previous_buildtime = recorder.GetLastBuildtime();
  525. std::string previous_version = recorder.GetLastVersion();
  526. if (previous_buildtime != buildtime || previous_version != version) {
  527. recorder.SetBuildtimeAndVersion(buildtime, version);
  528. version_changed = true;
  529. }
  530. session_id_ = local_state_->GetInteger(prefs::kMetricsSessionID);
  531. StabilityMetricsProvider provider(local_state_);
  532. const bool was_last_shutdown_clean = WasLastShutdownClean();
  533. if (!was_last_shutdown_clean) {
  534. provider.LogCrash(
  535. state_manager_->clean_exit_beacon()->browser_last_live_timestamp());
  536. #if BUILDFLAG(IS_ANDROID)
  537. if (!state_manager_->is_foreground_session()) {
  538. // Android can have background sessions in which the app may not come to
  539. // the foreground, so signal that Chrome should stop watching for crashes
  540. // here. This ensures that the termination of such sessions is not
  541. // considered a crash. If and when the app enters the foreground, Chrome
  542. // starts watching for crashes via MetricsService::OnAppEnterForeground().
  543. //
  544. // TODO(crbug/1232027): Such sessions do not yet exist on iOS. When they
  545. // do, it may not be possible to know at this point whether a session is a
  546. // background session.
  547. //
  548. // TODO(crbug/1245347): On WebLayer, it is not possible to know whether
  549. // it's a background session at this point.
  550. //
  551. // TODO(crbug/1245676): Ditto for WebView.
  552. state_manager_->clean_exit_beacon()->WriteBeaconValue(true);
  553. }
  554. #endif // BUILDFLAG(IS_ANDROID)
  555. }
  556. // HasPreviousSessionData is called first to ensure it is never bypassed.
  557. const bool is_initial_stability_log_required =
  558. delegating_provider_.HasPreviousSessionData() || !was_last_shutdown_clean;
  559. bool has_initial_stability_log = false;
  560. if (is_initial_stability_log_required) {
  561. // If the previous session didn't exit cleanly, or if any provider
  562. // explicitly requests it, prepare an initial stability log -
  563. // provided UMA is enabled.
  564. if (state_manager_->IsMetricsReportingEnabled()) {
  565. has_initial_stability_log = PrepareInitialStabilityLog(previous_version);
  566. }
  567. }
  568. // If the version changed, but no initial stability log was generated, clear
  569. // the stability stats from the previous version (so that they don't get
  570. // attributed to the current version). This could otherwise happen due to a
  571. // number of different edge cases, such as if the last version crashed before
  572. // it could save off a system profile or if UMA reporting is disabled (which
  573. // normally results in stats being accumulated).
  574. if (version_changed && !has_initial_stability_log)
  575. ClearSavedStabilityMetrics();
  576. // If the version changed, the system profile is obsolete and needs to be
  577. // cleared. This is to avoid the stability data misattribution that could
  578. // occur if the current version crashed before saving its own system profile.
  579. // Note however this clearing occurs only after preparing the initial
  580. // stability log, an operation that requires the previous version's system
  581. // profile. At this point, stability metrics pertaining to the previous
  582. // version have been cleared.
  583. if (version_changed)
  584. recorder.ClearEnvironmentFromPrefs();
  585. // Update session ID.
  586. ++session_id_;
  587. local_state_->SetInteger(prefs::kMetricsSessionID, session_id_);
  588. // Notify stability metrics providers about the launch.
  589. provider.LogLaunch();
  590. // Call GetUptimes() for the first time, thus allowing all later calls
  591. // to record incremental uptimes accurately.
  592. base::TimeDelta ignored_uptime_parameter;
  593. base::TimeDelta startup_uptime;
  594. GetUptimes(local_state_, &startup_uptime, &ignored_uptime_parameter);
  595. DCHECK_EQ(0, startup_uptime.InMicroseconds());
  596. }
  597. void MetricsService::OnUserAction(const std::string& action,
  598. base::TimeTicks action_time) {
  599. log_manager_.current_log()->RecordUserAction(action, action_time);
  600. HandleIdleSinceLastTransmission(false);
  601. }
  602. void MetricsService::FinishedInitTask() {
  603. DCHECK_EQ(INIT_TASK_SCHEDULED, state_);
  604. state_ = INIT_TASK_DONE;
  605. if (!base::FeatureList::IsEnabled(
  606. kConsolidateMetricsServiceInitialLogLogic)) {
  607. // Create the initial log.
  608. if (!initial_metrics_log_) {
  609. initial_metrics_log_ = CreateLog(MetricsLog::ONGOING_LOG);
  610. // Note: We explicitly do not call OnDidCreateMetricsLog() here, as this
  611. // function would have already been called in Start() and this log will
  612. // already contain any histograms logged there. OnDidCreateMetricsLog()
  613. // will be called again after the initial log is closed, for the next log.
  614. // TODO(crbug.com/1171830): Consider getting rid of
  615. // |initial_metrics_log_|.
  616. }
  617. }
  618. rotation_scheduler_->InitTaskComplete();
  619. }
  620. void MetricsService::GetUptimes(PrefService* pref,
  621. base::TimeDelta* incremental_uptime,
  622. base::TimeDelta* uptime) {
  623. base::TimeTicks now = base::TimeTicks::Now();
  624. // If this is the first call, init |first_updated_time_| and
  625. // |last_updated_time_|.
  626. if (last_updated_time_.is_null()) {
  627. first_updated_time_ = now;
  628. last_updated_time_ = now;
  629. }
  630. *incremental_uptime = now - last_updated_time_;
  631. *uptime = now - first_updated_time_;
  632. last_updated_time_ = now;
  633. }
  634. //------------------------------------------------------------------------------
  635. // Recording control methods
  636. void MetricsService::OpenNewLog() {
  637. DCHECK(!log_manager_.current_log());
  638. log_manager_.BeginLoggingWithLog(CreateLog(MetricsLog::ONGOING_LOG));
  639. delegating_provider_.OnDidCreateMetricsLog();
  640. DCHECK_NE(CONSTRUCTED, state_);
  641. if (state_ == INITIALIZED) {
  642. // We only need to schedule that run once.
  643. state_ = INIT_TASK_SCHEDULED;
  644. base::TimeDelta initialization_delay = base::Seconds(
  645. client_->ShouldStartUpFastForTesting() ? 0
  646. : kInitializationDelaySeconds);
  647. base::SequencedTaskRunnerHandle::Get()->PostDelayedTask(
  648. FROM_HERE,
  649. base::BindOnce(&MetricsService::StartInitTask,
  650. self_ptr_factory_.GetWeakPtr()),
  651. initialization_delay);
  652. base::SequencedTaskRunnerHandle::Get()->PostDelayedTask(
  653. FROM_HERE,
  654. base::BindOnce(&MetricsService::PrepareProviderMetricsTask,
  655. self_ptr_factory_.GetWeakPtr()),
  656. 2 * initialization_delay);
  657. }
  658. }
  659. void MetricsService::StartInitTask() {
  660. delegating_provider_.AsyncInit(base::BindOnce(
  661. &MetricsService::FinishedInitTask, self_ptr_factory_.GetWeakPtr()));
  662. }
  663. void MetricsService::CloseCurrentLog() {
  664. if (!log_manager_.current_log())
  665. return;
  666. // If a persistent allocator is in use, update its internal histograms (such
  667. // as how much memory is being used) before reporting.
  668. base::PersistentHistogramAllocator* allocator =
  669. base::GlobalHistogramAllocator::Get();
  670. if (allocator)
  671. allocator->UpdateTrackingHistograms();
  672. // Put incremental data (histogram deltas, and realtime stats deltas) at the
  673. // end of all log transmissions (initial log handles this separately).
  674. // RecordIncrementalStabilityElements only exists on the derived
  675. // MetricsLog class.
  676. MetricsLog* current_log = log_manager_.current_log();
  677. DCHECK(current_log);
  678. RecordCurrentEnvironment(current_log, /*complete=*/true);
  679. base::TimeDelta incremental_uptime;
  680. base::TimeDelta uptime;
  681. GetUptimes(local_state_, &incremental_uptime, &uptime);
  682. current_log->RecordCurrentSessionData(incremental_uptime, uptime,
  683. &delegating_provider_, local_state_);
  684. RecordCurrentHistograms();
  685. current_log->TruncateEvents();
  686. DVLOG(1) << "Generated an ongoing log.";
  687. log_manager_.FinishCurrentLog(log_store());
  688. }
  689. void MetricsService::PushPendingLogsToPersistentStorage() {
  690. if (state_ < SENDING_LOGS)
  691. return; // We didn't and still don't have time to get plugin list etc.
  692. CloseCurrentLog();
  693. log_store()->TrimAndPersistUnsentLogs(/*overwrite_in_memory_store=*/true);
  694. }
  695. //------------------------------------------------------------------------------
  696. // Transmission of logs methods
  697. void MetricsService::StartSchedulerIfNecessary() {
  698. // Never schedule cutting or uploading of logs in test mode.
  699. if (test_mode_active_)
  700. return;
  701. // Even if reporting is disabled, the scheduler is needed to trigger the
  702. // creation of the initial log, which must be done in order for any logs to be
  703. // persisted on shutdown or backgrounding.
  704. if (recording_active() && (reporting_active() || state_ < SENDING_LOGS)) {
  705. rotation_scheduler_->Start();
  706. reporting_service_.Start();
  707. }
  708. }
  709. void MetricsService::StartScheduledUpload() {
  710. DVLOG(1) << "StartScheduledUpload";
  711. DCHECK(state_ >= INIT_TASK_DONE);
  712. // If we're getting no notifications, then the log won't have much in it, and
  713. // it's possible the computer is about to go to sleep, so don't upload and
  714. // stop the scheduler.
  715. // If recording has been turned off, the scheduler doesn't need to run.
  716. // If reporting is off, proceed if the initial log hasn't been created, since
  717. // that has to happen in order for logs to be cut and stored when persisting.
  718. // TODO(stuartmorgan): Call Stop() on the scheduler when reporting and/or
  719. // recording are turned off instead of letting it fire and then aborting.
  720. if (idle_since_last_transmission_ || !recording_active() ||
  721. (!reporting_active() && state_ >= SENDING_LOGS)) {
  722. rotation_scheduler_->Stop();
  723. rotation_scheduler_->RotationFinished();
  724. return;
  725. }
  726. if (base::FeatureList::IsEnabled(kConsolidateMetricsServiceInitialLogLogic)) {
  727. // The first ongoing log should be collected prior to sending any unsent
  728. // logs.
  729. if (state_ == INIT_TASK_DONE) {
  730. client_->CollectFinalMetricsForLog(
  731. base::BindOnce(&MetricsService::OnFinalLogInfoCollectionDone,
  732. self_ptr_factory_.GetWeakPtr()));
  733. return;
  734. }
  735. }
  736. // If there are unsent logs, send the next one. If not, start the asynchronous
  737. // process of finalizing the current log for upload.
  738. bool send_unsent_logs =
  739. base::FeatureList::IsEnabled(kConsolidateMetricsServiceInitialLogLogic)
  740. ? has_unsent_logs()
  741. : state_ == SENDING_LOGS && has_unsent_logs();
  742. if (send_unsent_logs) {
  743. reporting_service_.Start();
  744. rotation_scheduler_->RotationFinished();
  745. } else {
  746. // There are no logs left to send, so start creating a new one.
  747. client_->CollectFinalMetricsForLog(
  748. base::BindOnce(&MetricsService::OnFinalLogInfoCollectionDone,
  749. self_ptr_factory_.GetWeakPtr()));
  750. }
  751. }
  752. void MetricsService::OnFinalLogInfoCollectionDone() {
  753. DVLOG(1) << "OnFinalLogInfoCollectionDone";
  754. if (base::FeatureList::IsEnabled(kConsolidateMetricsServiceInitialLogLogic)) {
  755. DCHECK(state_ >= INIT_TASK_DONE);
  756. state_ = SENDING_LOGS;
  757. }
  758. // Abort if metrics were turned off during the final info gathering.
  759. if (!recording_active()) {
  760. rotation_scheduler_->Stop();
  761. rotation_scheduler_->RotationFinished();
  762. return;
  763. }
  764. if (base::FeatureList::IsEnabled(kConsolidateMetricsServiceInitialLogLogic)) {
  765. CloseCurrentLog();
  766. OpenNewLog();
  767. // Trim and store unsent logs, including the log that was just closed, so
  768. // that they're not lost in case of a crash before upload time. However, the
  769. // in-memory log store is unchanged. I.e., logs that are trimmed will still
  770. // be available in memory. This is to give the log that was just created a
  771. // chance to be sent in case it is trimmed. After uploading (whether
  772. // successful or not), the log store is trimmed and stored again, and at
  773. // that time, the in-memory log store will be updated.
  774. log_store()->TrimAndPersistUnsentLogs(/*overwrite_in_memory_store=*/false);
  775. } else {
  776. if (state_ == INIT_TASK_DONE) {
  777. PrepareInitialMetricsLog();
  778. } else {
  779. DCHECK_EQ(SENDING_LOGS, state_);
  780. CloseCurrentLog();
  781. OpenNewLog();
  782. }
  783. }
  784. reporting_service_.Start();
  785. rotation_scheduler_->RotationFinished();
  786. HandleIdleSinceLastTransmission(true);
  787. }
  788. bool MetricsService::PrepareInitialStabilityLog(
  789. const std::string& prefs_previous_version) {
  790. DCHECK_EQ(CONSTRUCTED, state_);
  791. std::unique_ptr<MetricsLog> initial_stability_log(
  792. CreateLog(MetricsLog::INITIAL_STABILITY_LOG));
  793. // Do not call OnDidCreateMetricsLog here because the stability log describes
  794. // stats from the _previous_ session.
  795. if (!initial_stability_log->LoadSavedEnvironmentFromPrefs(local_state_))
  796. return false;
  797. log_manager_.PauseCurrentLog();
  798. log_manager_.BeginLoggingWithLog(std::move(initial_stability_log));
  799. // Note: Some stability providers may record stability stats via histograms,
  800. // so this call has to be after BeginLoggingWithLog().
  801. log_manager_.current_log()->RecordPreviousSessionData(&delegating_provider_,
  802. local_state_);
  803. RecordCurrentStabilityHistograms();
  804. DVLOG(1) << "Generated a stability log.";
  805. log_manager_.FinishCurrentLog(log_store());
  806. log_manager_.ResumePausedLog();
  807. // Store unsent logs, including the stability log that was just saved, so
  808. // that they're not lost in case of a crash before upload time.
  809. log_store()->TrimAndPersistUnsentLogs(/*overwrite_in_memory_store=*/true);
  810. return true;
  811. }
  812. void MetricsService::PrepareInitialMetricsLog() {
  813. DCHECK_EQ(INIT_TASK_DONE, state_);
  814. RecordCurrentEnvironment(initial_metrics_log_.get(), /*complete=*/true);
  815. base::TimeDelta incremental_uptime;
  816. base::TimeDelta uptime;
  817. GetUptimes(local_state_, &incremental_uptime, &uptime);
  818. // Histograms only get written to the current log, so make the new log current
  819. // before writing them.
  820. log_manager_.PauseCurrentLog();
  821. log_manager_.BeginLoggingWithLog(std::move(initial_metrics_log_));
  822. // Note: Some stability providers may record stability stats via histograms,
  823. // so this call has to be after BeginLoggingWithLog().
  824. log_manager_.current_log()->RecordCurrentSessionData(
  825. base::TimeDelta(), base::TimeDelta(), &delegating_provider_,
  826. local_state_);
  827. RecordCurrentHistograms();
  828. DVLOG(1) << "Generated an initial log.";
  829. log_manager_.FinishCurrentLog(log_store());
  830. log_manager_.ResumePausedLog();
  831. // We call OnDidCreateMetricsLog() here for the next log. Normally, this is
  832. // called when the log is created, but in this special case, the log we paused
  833. // was created much earlier - by Start(). The histograms that were recorded
  834. // via OnDidCreateMetricsLog() are now in the initial metrics log we just
  835. // processed, so we need to record new ones for the next log.
  836. delegating_provider_.OnDidCreateMetricsLog();
  837. // Store unsent logs, including the initial log that was just saved, so
  838. // that they're not lost in case of a crash before upload time.
  839. log_store()->TrimAndPersistUnsentLogs(/*overwrite_in_memory_store=*/true);
  840. state_ = SENDING_LOGS;
  841. }
  842. void MetricsService::RegisterMetricsProvider(
  843. std::unique_ptr<MetricsProvider> provider) {
  844. DCHECK_EQ(CONSTRUCTED, state_);
  845. delegating_provider_.RegisterMetricsProvider(std::move(provider));
  846. }
  847. void MetricsService::CheckForClonedInstall() {
  848. state_manager_->CheckForClonedInstall();
  849. }
  850. bool MetricsService::ShouldResetClientIdsOnClonedInstall() {
  851. return state_manager_->ShouldResetClientIdsOnClonedInstall();
  852. }
  853. std::unique_ptr<MetricsLog> MetricsService::CreateLog(
  854. MetricsLog::LogType log_type) {
  855. auto new_metrics_log = std::make_unique<MetricsLog>(
  856. state_manager_->client_id(), session_id_, log_type, client_);
  857. #if BUILDFLAG(IS_CHROMEOS_ASH)
  858. absl::optional<std::string> user_id = GetCurrentUserId();
  859. if (user_id.has_value())
  860. new_metrics_log->SetUserId(user_id.value());
  861. #endif // BUILDFLAG(IS_CHROMEOS_ASH)
  862. return new_metrics_log;
  863. }
  864. base::CallbackListSubscription MetricsService::AddEnablementObserver(
  865. const base::RepeatingCallback<void(bool)>& observer) {
  866. return enablement_observers_.Add(observer);
  867. }
  868. void MetricsService::SetPersistentSystemProfile(
  869. const std::string& serialized_proto,
  870. bool complete) {
  871. GlobalPersistentSystemProfile::GetInstance()->SetSystemProfile(
  872. serialized_proto, complete);
  873. }
  874. // static
  875. std::string MetricsService::RecordCurrentEnvironmentHelper(
  876. MetricsLog* log,
  877. PrefService* local_state,
  878. DelegatingProvider* delegating_provider) {
  879. const SystemProfileProto& system_profile =
  880. log->RecordEnvironment(delegating_provider);
  881. EnvironmentRecorder recorder(local_state);
  882. return recorder.SerializeAndRecordEnvironmentToPrefs(system_profile);
  883. }
  884. void MetricsService::RecordCurrentEnvironment(MetricsLog* log, bool complete) {
  885. DCHECK(client_);
  886. std::string serialized_proto =
  887. RecordCurrentEnvironmentHelper(log, local_state_, &delegating_provider_);
  888. SetPersistentSystemProfile(serialized_proto, complete);
  889. client_->OnEnvironmentUpdate(&serialized_proto);
  890. }
  891. void MetricsService::RecordCurrentHistograms() {
  892. DCHECK(log_manager_.current_log());
  893. base::StatisticsRecorder::PrepareDeltas(
  894. /*include_persistent=*/true, base::Histogram::kNoFlags,
  895. base::Histogram::kUmaTargetedHistogramFlag, &histogram_snapshot_manager_);
  896. delegating_provider_.RecordHistogramSnapshots(&histogram_snapshot_manager_);
  897. }
  898. void MetricsService::RecordCurrentStabilityHistograms() {
  899. DCHECK(log_manager_.current_log());
  900. // "true" indicates that StatisticsRecorder should include histograms held in
  901. // persistent storage.
  902. base::StatisticsRecorder::PrepareDeltas(
  903. true, base::Histogram::kNoFlags,
  904. base::Histogram::kUmaStabilityHistogramFlag,
  905. &histogram_snapshot_manager_);
  906. delegating_provider_.RecordInitialHistogramSnapshots(
  907. &histogram_snapshot_manager_);
  908. }
  909. void MetricsService::PrepareProviderMetricsLogDone(
  910. std::unique_ptr<MetricsLog::IndependentMetricsLoader> loader,
  911. bool success) {
  912. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  913. DCHECK(independent_loader_active_);
  914. DCHECK(loader);
  915. if (success) {
  916. log_manager_.PauseCurrentLog();
  917. log_manager_.BeginLoggingWithLog(loader->ReleaseLog());
  918. log_manager_.FinishCurrentLog(log_store());
  919. log_manager_.ResumePausedLog();
  920. }
  921. independent_loader_active_ = false;
  922. }
  923. bool MetricsService::PrepareProviderMetricsLog() {
  924. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  925. // If something is still pending, stop now and indicate that there is
  926. // still work to do.
  927. if (independent_loader_active_)
  928. return true;
  929. // Check each provider in turn for data.
  930. for (auto& provider : delegating_provider_.GetProviders()) {
  931. if (provider->HasIndependentMetrics()) {
  932. // Create a new log. This will have some default values injected in it
  933. // but those will be overwritten when an embedded profile is extracted.
  934. std::unique_ptr<MetricsLog> log = CreateLog(MetricsLog::INDEPENDENT_LOG);
  935. // Note that something is happening. This must be set before the
  936. // operation is requested in case the loader decides to do everything
  937. // immediately rather than as a background task.
  938. independent_loader_active_ = true;
  939. // Give the new log to a loader for management and then run it on the
  940. // provider that has something to give. A copy of the pointer is needed
  941. // because the unique_ptr may get moved before the value can be used
  942. // to call Run().
  943. std::unique_ptr<MetricsLog::IndependentMetricsLoader> loader =
  944. std::make_unique<MetricsLog::IndependentMetricsLoader>(
  945. std::move(log));
  946. MetricsLog::IndependentMetricsLoader* loader_ptr = loader.get();
  947. loader_ptr->Run(
  948. base::BindOnce(&MetricsService::PrepareProviderMetricsLogDone,
  949. self_ptr_factory_.GetWeakPtr(), std::move(loader)),
  950. provider.get());
  951. // Something was found so there may still be more work to do.
  952. return true;
  953. }
  954. }
  955. // Nothing was found so indicate there is no more work to do.
  956. return false;
  957. }
  958. void MetricsService::PrepareProviderMetricsTask() {
  959. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  960. bool found = PrepareProviderMetricsLog();
  961. base::TimeDelta next_check = found ? base::Seconds(5) : base::Minutes(15);
  962. base::SequencedTaskRunnerHandle::Get()->PostDelayedTask(
  963. FROM_HERE,
  964. base::BindOnce(&MetricsService::PrepareProviderMetricsTask,
  965. self_ptr_factory_.GetWeakPtr()),
  966. next_check);
  967. }
  968. void MetricsService::UpdateLastLiveTimestampTask() {
  969. state_manager_->clean_exit_beacon()->UpdateLastLiveTimestamp();
  970. // Schecule the next update.
  971. StartUpdatingLastLiveTimestamp();
  972. }
  973. } // namespace metrics