15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef CHROME_BROWSER_CHROMEOS_BOOT_TIMES_LOADER_H_ 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define CHROME_BROWSER_CHROMEOS_BOOT_TIMES_LOADER_H_ 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <set> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string> 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/atomic_sequence_num.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/callback_forward.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/compiler_specific.h" 145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/task/cancelable_task_tracker.h" 15eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_observer.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_registrar.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/render_widget_host.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)class PrefService; 2146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace chromeos { 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// BootTimesLoader loads the bootimes of Chrome OS from the file system. 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Loading is done asynchronously on the file thread. Once loaded, 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// BootTimesLoader calls back to a method of your choice with the boot times. 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// To use BootTimesLoader, do the following: 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// . In your class define a member field of type chromeos::BootTimesLoader and 305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// base::CancelableTaskTracker. 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// . Define the callback method, something like: 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// void OnBootTimesLoaded(const BootTimesLoader::BootTimes& boot_times); 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// . When you want the version invoke: loader.GetBootTimes(callback, &tracker_); 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class BootTimesLoader : public content::NotificationObserver { 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BootTimesLoader(); 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~BootTimesLoader(); 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static BootTimesLoader* Get(); 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Add a time marker for login. A timeline will be dumped to 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // /tmp/login-times-sent after login is done. If |send_to_uma| is true 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the time between this marker and the last will be sent to UMA with 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the identifier BootTime.|marker_name|. 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void AddLoginTimeMarker(const std::string& marker_name, bool send_to_uma); 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Add a time marker for logout. A timeline will be dumped to 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // /tmp/logout-times-sent after logout is done. If |send_to_uma| is true 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the time between this marker and the last will be sent to UMA with 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the identifier ShutdownTime.|marker_name|. 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void AddLogoutTimeMarker(const std::string& marker_name, bool send_to_uma); 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Records current uptime and disk usage for metrics use. 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Posts task to file thread. 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // name will be used as part of file names in /tmp. 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Existing stats files will not be overwritten. 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void RecordCurrentStats(const std::string& name); 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Saves away the stats at main, so the can be recorded later. At main() time 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the necessary threads don't exist yet for recording the data. 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void SaveChromeMainStats(); 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Records the data previously saved by SaveChromeMainStats(), using the 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // file thread. Existing stats files will not be overwritten. 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void RecordChromeMainStats(); 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Records the time that a login was attempted. This will overwrite any 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // previous login attempt times. 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void RecordLoginAttempted(); 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // content::NotificationObserver implementation. 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void Observe(int type, 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const content::NotificationSource& source, 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const content::NotificationDetails& details) OVERRIDE; 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 76cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Records "LoginDone" event. 77cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) void LoginDone(bool is_user_new); 78cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Writes the logout times to a /tmp/logout-times-sent. Unlike login 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // times, we manually call this function for logout times, as we cannot 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // rely on notification service to tell when the logout is done. 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void WriteLogoutTimes(); 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 84cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Mark that WriteLogoutTimes should handle restart. 85cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) void set_restart_requested() { restart_requested_ = true; } 86cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 8746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // This is called on Chrome process startup to write saved logout stats. 8846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) void OnChromeProcessStart(); 8946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 9046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // This saves logout-started metric to Local State. 9146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) void OnLogoutStarted(PrefService* state); 9246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // BootTimesLoader calls into the Backend on the file thread to load 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the boot times. 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) class Backend : public base::RefCountedThreadSafe<Backend> { 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Backend() {} 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) friend class base::RefCountedThreadSafe<Backend>; 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ~Backend() {} 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(Backend); 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) class TimeMarker { 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TimeMarker(const std::string& name, bool send_to_uma) 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : name_(name), 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) time_(base::Time::NowFromSystemTime()), 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) send_to_uma_(send_to_uma) {} 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string name() const { return name_; } 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Time time() const { return time_; } 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool send_to_uma() const { return send_to_uma_; } 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // comparitor for sorting 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool operator<(const TimeMarker& other) const { 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return time_ < other.time_; 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) friend class std::vector<TimeMarker>; 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string name_; 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Time time_; 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool send_to_uma_; 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) class Stats { 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 13246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // Initializes stats with current /proc values. 13346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) static Stats GetCurrentStats(); 13446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 13546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // Returns JSON representation. 13646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) std::string SerializeToString() const; 13746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 13846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // Creates new object from JSON representation. 13946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) static Stats DeserializeFromString(const std::string& value); 14046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 14146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const std::string& uptime() const { return uptime_; } 14246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const std::string& disk() const { return disk_; } 14346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 14446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // Writes "uptime in seconds" to result. (This is first field in uptime_.) 14546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // Returns true on successful conversion. 14646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) bool UptimeDouble(double* result) const; 14746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 14846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) void RecordStats(const std::string& name) const; 14946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) void RecordStatsWithCallback(const std::string& name, 15046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const base::Closure& callback) const; 15146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 15246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) private: 15346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // Runs on BlockingPool 15446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) void RecordStatsImpl(const std::string& name) const; 15546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 15646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) std::string uptime_; 15746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) std::string disk_; 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static void WriteTimes(const std::string base_name, 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string uma_name, 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string uma_prefix, 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<TimeMarker> login_times); 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static void AddMarker(std::vector<TimeMarker>* vector, TimeMarker marker); 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // Clear saved logout-started metric in Local State. 16746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // This method is called when logout-state was writen to file. 16846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) static void ClearLogoutStartedLastPreference(); 16946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Used to hold the stats at main(). 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Stats chrome_main_stats_; 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<Backend> backend_; 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Used to track notifications for login. 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::NotificationRegistrar registrar_; 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::AtomicSequenceNumber num_tabs_; 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool have_registered_; 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<TimeMarker> login_time_markers_; 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<TimeMarker> logout_time_markers_; 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::set<content::RenderWidgetHost*> render_widget_hosts_loading_; 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 183cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) bool login_done_; 184cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 185cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) bool restart_requested_; 186cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(BootTimesLoader); 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace chromeos 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // CHROME_BROWSER_CHROMEOS_BOOT_TIMES_LOADER_H_ 193