perf_provider_chromeos.cc revision c5cede9ae108bb15f6b7a8aea21c7e1fefa2834c
12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file.
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <string>
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/bind.h"
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/bind_helpers.h"
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/callback.h"
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/command_line.h"
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/compiler_specific.h"
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/metrics/histogram.h"
13868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/rand_util.h"
14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/strings/string_number_conversions.h"
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/threading/sequenced_worker_pool.h"
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/metrics/perf_provider_chromeos.h"
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/profiles/profile.h"
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/browser.h"
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/browser_list.h"
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/browser_list_observer.h"
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/common/chrome_switches.h"
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chromeos/dbus/dbus_thread_manager.h"
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chromeos/dbus/debug_daemon_client.h"
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace {
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Default time in seconds between invocations of perf.
28c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// This period is roughly 6.5 hours.
29c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// This is chosen to be relatively prime with the number of seconds in:
30c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// - one minute (60)
31c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// - one hour (3600)
32c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// - one day (86400)
33868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)const size_t kPerfCommandIntervalDefaultSeconds = 23093;
34868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
35868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// The first collection interval is different from the interval above. This is
36868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// because we want to collect the first profile quickly after Chrome is started.
37868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// If this period is too long, the user will log off and Chrome will be killed
38868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// before it is triggered. The following 2 variables determine the upper and
39868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// lower bound on the interval.
40868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// The reason we do not always want to collect the initial profile after a fixed
41868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// period is to not over-represent task X in the profile where task X always
42868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// runs at a fixed period after start-up. By selecting a period randomly between
43868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// a lower and upper bound, we will hopefully collect a more fair profile.
44868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)const size_t kPerfCommandStartIntervalLowerBoundMinutes = 10;
45868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
46868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)const size_t kPerfCommandStartIntervalUpperBoundMinutes = 20;
47868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Default time in seconds perf is run for.
49868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)const size_t kPerfCommandDurationDefaultSeconds = 2;
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
51c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch// Limit the total size of protobufs that can be cached, so they don't take up
52c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch// too much memory. If the size of cached protobufs exceeds this value, stop
53c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch// collecting further perf data. The current value is 4 MB.
54c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochconst size_t kCachedPerfDataProtobufSizeThreshold = 4 * 1024 * 1024;
55c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
56a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)// Enumeration representing success and various failure modes for collecting and
57a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)// sending perf data.
58a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)enum GetPerfDataOutcome {
59a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  SUCCESS,
60a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  NOT_READY_TO_UPLOAD,
61a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  NOT_READY_TO_COLLECT,
62a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  INCOGNITO_ACTIVE,
63a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  INCOGNITO_LAUNCHED,
64a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  PROTOBUF_NOT_PARSED,
65a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  NUM_OUTCOMES
66a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)};
67a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
68a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)// Name of the histogram that represents the success and various failure modes
69a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)// for collecting and sending perf data.
70a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)const char kGetPerfDataOutcomeHistogram[] = "UMA.Perf.GetData";
71a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
72a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)void AddToPerfHistogram(GetPerfDataOutcome outcome) {
73a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  UMA_HISTOGRAM_ENUMERATION(kGetPerfDataOutcomeHistogram,
74a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                            outcome,
75a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                            NUM_OUTCOMES);
76a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)}
77a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}  // namespace
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace metrics {
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// This class must be created and used on the UI thread. It watches for any
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// incognito window being opened from the time it is instantiated to the time it
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// is destroyed.
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class WindowedIncognitoObserver : public chrome::BrowserListObserver {
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  WindowedIncognitoObserver() : incognito_launched_(false) {
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    BrowserList::AddObserver(this);
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~WindowedIncognitoObserver() {
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    BrowserList::RemoveObserver(this);
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // This method can be checked to see whether any incognito window has been
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // opened since the time this object was created.
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool incognito_launched() {
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return incognito_launched_;
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // chrome::BrowserListObserver implementation.
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnBrowserAdded(Browser* browser) OVERRIDE {
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (browser->profile()->IsOffTheRecord())
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      incognito_launched_ = true;
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool incognito_launched_;
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)PerfProvider::PerfProvider()
113c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      : weak_factory_(this) {
114868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  size_t collection_interval_minutes = base::RandInt(
115868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      kPerfCommandStartIntervalLowerBoundMinutes,
116868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      kPerfCommandStartIntervalUpperBoundMinutes);
117868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ScheduleCollection(base::TimeDelta::FromMinutes(collection_interval_minutes));
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)PerfProvider::~PerfProvider() {}
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
122c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochbool PerfProvider::GetPerfData(std::vector<PerfDataProto>* perf_data) {
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(CalledOnValidThread());
124c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  if (cached_perf_data_.empty()) {
125a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    AddToPerfHistogram(NOT_READY_TO_UPLOAD);
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
127a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  }
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
129c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  perf_data->swap(cached_perf_data_);
130c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  cached_perf_data_.clear();
131a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
132a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  AddToPerfHistogram(SUCCESS);
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
136868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void PerfProvider::ScheduleCollection(const base::TimeDelta& interval) {
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(CalledOnValidThread());
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (timer_.IsRunning())
1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
141868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  timer_.Start(FROM_HERE, interval, this,
142868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)               &PerfProvider::CollectIfNecessaryAndReschedule);
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void PerfProvider::CollectIfNecessary() {
1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(CalledOnValidThread());
147c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
148c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  // Do not collect further data if we've already collected a substantial amount
149c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  // of data, as indicated by |kCachedPerfDataProtobufSizeThreshold|.
150c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  size_t cached_perf_data_size = 0;
151c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  for (size_t i = 0; i < cached_perf_data_.size(); ++i) {
152c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    cached_perf_data_size += cached_perf_data_[i].ByteSize();
153c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  }
154c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  if (cached_perf_data_size >= kCachedPerfDataProtobufSizeThreshold) {
155a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    AddToPerfHistogram(NOT_READY_TO_COLLECT);
1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
157a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  }
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // For privacy reasons, Chrome should only collect perf data if there is no
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // incognito session active (or gets spawned during the collection).
161a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  if (BrowserList::IsOffTheRecordSessionActive()) {
162a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    AddToPerfHistogram(INCOGNITO_ACTIVE);
1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
164a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  }
1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<WindowedIncognitoObserver> incognito_observer(
1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new WindowedIncognitoObserver);
1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  chromeos::DebugDaemonClient* client =
1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      chromeos::DBusThreadManager::Get()->GetDebugDaemonClient();
1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::TimeDelta collection_duration = base::TimeDelta::FromSeconds(
1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      kPerfCommandDurationDefaultSeconds);
1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  client->GetPerfData(collection_duration.InSeconds(),
1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                      base::Bind(&PerfProvider::ParseProtoIfValid,
1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 weak_factory_.GetWeakPtr(),
1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 base::Passed(&incognito_observer)));
1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
181868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void PerfProvider::CollectIfNecessaryAndReschedule() {
182868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  CollectIfNecessary();
183868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ScheduleCollection(
184868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      base::TimeDelta::FromSeconds(kPerfCommandIntervalDefaultSeconds));
185868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void PerfProvider::ParseProtoIfValid(
1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<WindowedIncognitoObserver> incognito_observer,
1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::vector<uint8>& data) {
1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(CalledOnValidThread());
1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
192a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  if (incognito_observer->incognito_launched()) {
193a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    AddToPerfHistogram(INCOGNITO_LAUNCHED);
1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
195a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  }
1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
197c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  PerfDataProto perf_data_proto;
198c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  if (!perf_data_proto.ParseFromArray(data.data(), data.size())) {
199a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    AddToPerfHistogram(PROTOBUF_NOT_PARSED);
2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
203c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  // Append a new PerfDataProto to the |cached_perf_data_| vector and swap in
204c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  // the contents.
205c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  cached_perf_data_.resize(cached_perf_data_.size() + 1);
206c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  cached_perf_data_.back().Swap(&perf_data_proto);
2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}  // namespace metrics
210