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)#ifndef CHROME_BROWSER_METRICS_PERF_PROVIDER_CHROMEOS_H_
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define CHROME_BROWSER_METRICS_PERF_PROVIDER_CHROMEOS_H_
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <string>
9c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include <vector>
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/basictypes.h"
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/threading/non_thread_safe.h"
13eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h"
14eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/timer/timer.h"
15f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "chromeos/dbus/power_manager_client.h"
16cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chromeos/login/login_state.h"
1746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "components/metrics/proto/sampled_profile.pb.h"
18116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "content/public/browser/notification_observer.h"
19116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "content/public/browser/notification_registrar.h"
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace metrics {
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class WindowedIncognitoObserver;
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Provides access to ChromeOS perf data. perf aka "perf events" is a
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// performance profiling infrastructure built into the linux kernel. For more
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// information, see: https://perf.wiki.kernel.org/index.php/Main_Page.
28f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)class PerfProvider : public base::NonThreadSafe,
29116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                     public chromeos::PowerManagerClient::Observer,
30116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                     public content::NotificationObserver {
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PerfProvider();
33f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  virtual ~PerfProvider();
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Stores collected perf data protobufs in |sampled_profiles|. Clears all the
3646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // stored profile data. Returns true if it wrote to |sampled_profiles|.
3746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  bool GetSampledProfiles(std::vector<SampledProfile>* sampled_profiles);
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
40cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Class that listens for changes to the login state. When a normal user logs
41cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // in, it updates PerfProvider to start collecting data.
42cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  class LoginObserver : public chromeos::LoginState::Observer {
43cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)   public:
44cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    explicit LoginObserver(PerfProvider* perf_provider);
45cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
46cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // Called when either the login state or the logged in user type changes.
47cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // Activates |perf_provider_| to start collecting.
48cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    virtual void LoggedInStateChanged() OVERRIDE;
49cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
50cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)   private:
51cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // Points to a PerfProvider instance that can be turned on or off based on
52cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // the login state.
53cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    PerfProvider* perf_provider_;
54cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  };
55cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
56f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Called when a suspend finishes. This is either a successful suspend
57f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // followed by a resume, or a suspend that was canceled. Inherited from
58f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // PowerManagerClient::Observer.
59f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  virtual void SuspendDone(const base::TimeDelta& sleep_duration) OVERRIDE;
60f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
61f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Turns on perf collection. Resets the timer that's used to schedule
62cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // collections.
6346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  void OnUserLoggedIn();
64cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
65116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Called when a session restore has finished.
66116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Inherited from content::NotificationObserver.
67116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  virtual void Observe(int type,
68116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                       const content::NotificationSource& source,
69116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                       const content::NotificationDetails& details) OVERRIDE;
70116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
71cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Turns off perf collection. Does not delete any data that was already
72cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // collected and stored in |cached_perf_data_|.
73cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  void Deactivate();
74cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
7546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Selects a random time in the upcoming profiling interval that begins at
7646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // |next_profiling_interval_start_|. Schedules |timer_| to invoke
7746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // DoPeriodicCollection() when that time comes.
78116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  void ScheduleIntervalCollection();
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Collects perf data for a given |trigger_event|. Calls perf via the ChromeOS
8146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // debug daemon's dbus interface.
82f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  void CollectIfNecessary(scoped_ptr<SampledProfile> sampled_profile);
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Collects perf data on a repeating basis by calling CollectIfNecessary() and
8546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // reschedules it to be collected again.
8646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  void DoPeriodicCollection();
87868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
88116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Collects perf data after a resume. |sleep_duration| is the duration the
89116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // system was suspended before resuming. |time_after_resume_ms| is how long
90116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // ago the system resumed.
91116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  void CollectPerfDataAfterResume(const base::TimeDelta& sleep_duration,
92116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                  const base::TimeDelta& time_after_resume);
93116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
94116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Collects perf data after a session restore. |time_after_restore| is how
95116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // long ago the session restore started.
96116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  void CollectPerfDataAfterSessionRestore(
97116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      const base::TimeDelta& time_after_restore);
98116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
9946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Parses a perf data protobuf from the |data| passed in only if the
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // |incognito_observer| indicates that no incognito window had been opened
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // during the profile collection period.
10246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // |trigger_event| is the cause of the perf data collection.
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void ParseProtoIfValid(
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      scoped_ptr<WindowedIncognitoObserver> incognito_observer,
105f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      scoped_ptr<SampledProfile> sampled_profile,
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const std::vector<uint8>& data);
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Vector of SampledProfile protobufs containing perf profiles.
10946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  std::vector<SampledProfile> cached_perf_data_;
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // For scheduling collection of perf data.
112868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  base::OneShotTimer<PerfProvider> timer_;
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
114cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // For detecting when changes to the login state.
115cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  LoginObserver login_observer_;
116cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
11746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Record of the last login time.
11846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  base::TimeTicks login_time_;
11946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
12046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Record of the start of the upcoming profiling interval.
12146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  base::TimeTicks next_profiling_interval_start_;
12246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
123116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Used to register objects of this class as observers to be notified of
124116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // session restore events.
125116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  content::NotificationRegistrar session_restore_registrar_;
126116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
127116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Tracks the last time a session restore was collected.
128116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  base::TimeTicks last_session_restore_collection_time_;
129116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // To pass around the "this" pointer across threads safely.
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::WeakPtrFactory<PerfProvider> weak_factory_;
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(PerfProvider);
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
136c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}  // namespace metrics
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif  // CHROME_BROWSER_METRICS_PERF_PROVIDER_CHROMEOS_H_
139