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